Здравствуйте, Аноним, Вы писали:
А>Помогите написать паттерн для выкусывания текста из файла с мусором, может какой-нибудь более нормальный путь есть?
sscanf'ом здесь не обойдешься: он не запоминает, где закончил разбор.
Что считать текстом? Например, такое определение:
— текст — это последовательность слов, разделенных пробелами (общей длиной не менее 2 знаков)
— слово — это непустая последовательность букв [A-Za-z]
— код — это что угодно кроме текста
Строим конечный автомат:
START --> CODE, запомнить позицию C
CODE , A-Z|a-z --> TEXT1, запомнить позицию T
CODE , ? --> CODE
CODE , end --> вывести код от C до текущей, конец
TEXT1, A-Z|a-z|space --> TEXT, вывести код от C до T, сбросить C
TEXT1, ? --> CODE
TEXT1, end --> вывести код от C до текущей, конец
TEXT , A-Z|a-z|space --> TEXT
TEXT , ? --> CODE, вывести текст от T до текущей, сбросить T, запомнить C
TEXT , end --> вывести текст от T до текущей, конец
И пишем прогу
void print_begin();
void print_text(const char* s, int len);
void print_code(const char* s, int len);
void print_end();
void parse(const char* s)
{
print_begin();
const char* pc = s;
const char* pt = NULL;
char ch;
enum { CODE, TEXT1, TEXT } st = CODE;
while(true)
{
ch = *s;
switch(st)
{
case CODE:
if (ch == 0) { print_code(pc, s-pc); print_end(); return; }
else if(isalpha(ch)) { pt = s; st = TEXT1; }
else { }
break;
case TEXT1:
if (ch == 0) { print_code(pc, s-pc); print_end(); return; }
else if(isalpha(ch) || isspace(ch)) { print_code(pc, pt-pc); pc = NULL; }
else { st = CODE; pt = NULL; }
break;
case TEXT:
if (ch == 0) { print_text(pt, s-pt); print_end(); return; }
else if(isalpha(ch) || isspace(ch)) { }
else { print_text(pt, s-pt); st = CODE; pt = NULL; pc = s; }
break;
}
++s;
}
}
Вот примерно так.
(Программу не отлаживал, не обессудьте).