Зацикливание парсера
Я хотел бы знать, как я могу зациклить парсер, который я сделал. У меня есть несколько текстовых файлов, и я не знаю, что делать. Вот код
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
int parse(char **argv)
{
/* code that converts a text file to a string called file_contents */
char *target = NULL;
char *target2 = NULL;
char *start, *end;
const char *tag1 = "<item>";
const char *tag2 = "</item>";
if(start = strstr(file_contents, tag1))
{
start += strlen(tag1);
if(end = strstr(start, tag2))
{
target = (char *)malloc(end-start+1);
memcpy(target, start, end-start);
target[end - start] = '\0';
}
const char *tag3 = "<title>";
const char *tag4 = "</title>";
if(start = strstr(target, tag3))
{
start += strlen(tag3);
if(end = strstr(start, tag4))
{
target2 = (char *)malloc(end-start+1);
memcpy(target2, start, end-start);
target2[end-start] = '\0';
printf("%s\n", target2);
}
}
/* same code for other tags */
}
}
free(target);
return 2;
}
Образец текста это.
<item>
<title>blah blah</title>
<otherTags>blah blah</otherTags>
</item> <item>
<title>blah blah</title>
<otherTags>blah blah</otherTags>
</item> <item>
<title>blah blah</title>
<otherTags>blah blah</otherTags>
</item>
Мой код анализирует только первый элемент. Я новичок, так что направляй меня. Благодарю.
1 ответ
Похоже, все, что вам нужно сделать, это изменить свой if
к while
и просто держите указатели, двигаясь через строку, как вы идете. Я верю что меняюсь
if(start = strstr(file_contents, tag1))
в
start = file_contents;
while(start = strstr(start, tag1))
бы получить желаемое поведение (при условии, что остальная часть кода работает). Это просто продолжит цикл до тех пор, пока вы все еще получаете ненулевой возврат из strstr оставшейся строки (начиная с start
).
Как я уже упоминал в своем комментарии, я бы также порекомендовал вам изучить рекурсивный анализ, если вы готовы к этому; Похоже, это было бы здорово для вашего случая (отказ от ответственности: я не эксперт по парсерам). Кроме того, ваш код выглядит хорошо, особенно для самопровозглашенного новичка!
Изменить: Кажется, что ваш код нуждается в некоторой реструктуризации, по крайней мере, чтобы он зациклился, как я предлагаю. Вам следует избегать копирования строк и просто проходить по ним "вложенным" способом. Просто перестановка внутри и вокруг вашего оператора if
//These really should be static or #define'd, but that's another post
const char *tag1 = "<item>";
const char *tag2 = "</item>";
const char *tag3 = "<title>";
const char *tag4 = "</title>";
if(start = strstr(file_contents, tag1))
{
start += strlen(tag1);
if(start = strstr(target, tag3))
{
start += strlen(tag3);
if(end = strstr(start, tag4))
{
target2 = (char *)malloc(end-start+1);
memcpy(target2, start, end-start);
target2[end-start] = '\0';
printf("%s\n", target2); //Replacing this with fwrite would be faster
//with no malloc, but another post
free(target2); //Don't want to leak!
} //else, maybe return error code
}
/* same code for other tags */
start = strstr(start, tag2); //Find end of <item>
start += strlen(tag2); //Goto remaining string
}
Если это работает, то упомянутое ранее изменение должно пройти правильно. Если вы хотите придерживаться своего пути, вам понадобится другой способ отслеживать, где находится остаток вашей строки (strcpy
Вы упомянули в комментариях может работать, но это добавит много накладных расходов).