2013-02-23 3 views
0

У меня есть файл, который имеет следующий формат:Синтаксический файл в C с несколькими подобными блоками

abc dca 
2 
aa bb 
casca casss 

abc dca 
3 
aa bb 
casca casss 
casca casss 

abcd abcd 
0 

В основном это идет по блокам (в предыдущем примере, там будет 3 блока). Конкретный блок будет:

abc dca 
2 
aa bb 
casca casss 

во всех случаях мы имеем:
Первая линия: Всегда два слова, разделенные пробелом.
Вторая строка: A

Оттуда у нас будет столько строк, сколько у предыдущего номера, и каждая строка будет иметь всегда два слова.

Как я могу разобрать файл, чтобы для каждого блока я мог вызывать функцию, передающую некоторые вещи, которые я вычисляю с помощью того, что я нашел в блоке?

ответ

1

Используйте минимальное состояние машины:

#include <stdio.h> 
#include <string.h> 

int main(int qrgc, char **argv) 
{ 
char buff[111]; 
char one[10], two[10]; 
char left[10], right[10]; 
int num; 
size_t len; 
int state,rc; 

state =0; 

while(fgets (buff, sizeof buff, stdin)) { 
     len = strlen (buff); 
     while (len && buff[len-1] == '\n') buff[--len] = 0; 
     switch (state) { 
     case 0: 
       rc = sscanf(buff, "%s %s", left, right); 
       if (rc < 2) goto quit; 
       state=1; 
       break; 
     case 1: 
       rc = sscanf(buff, "%d", &num); 
       if (rc < 1) goto quit; 
       state=2; 
       break; 
     default: 
       if (!len) {state = 0; continue; } 
       rc = sscanf(buff, "%s %s", one, two); 
       if (rc < 2) goto quit; 
       break; 
       } 
     } 
quit: ; 
return 0; 
} 
+0

я не знаю. Он работает здесь (просто протестировал его) – wildplasser

+0

wildplasser это действительно хороший подход. Однако у меня есть сомнения. Для каждого блока мне нужно вызвать функцию и передать найденные параметры (слова первой строки и слова, которые появляются после целого числа). Выполняя конечный автомат, я действительно не знаю, в каком блоке я прав? как я могу это решить? Я имею в виду, допустим, что для первого блока я бы назвал функцию вроде doLogic (abc, dca, mapping_rules); Где mapping_rules - это массив структур, которые содержат начало и судьбу. Происхождение было бы аа и судьбой bb для первой линии, а casca и casss для второй. –

+0

Да, это всего лишь скелет. Вам нужно будет добавить фактическую полезную нагрузку: выделить узлы, перераспределить массивы и т. Д. Это * может быть * сделано в подфункциях, но если оно мало, оно также может быть добавлено к блокам case. – wildplasser

0

Существует много способов сделать это. Два, о которых я думал, это:

Если файл не очень большой, вы можете прочитать его все в список строк (по одной строке для каждой строки).

Другой способ - передать функцию, которая принимает дескриптор файла и предыдущий блок.

(я не хочу писать динамические массивы в C)

Смежные вопросы