Зацикливание парсера

Я хотел бы знать, как я могу зациклить парсер, который я сделал. У меня есть несколько текстовых файлов, и я не знаю, что делать. Вот код

#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 Вы упомянули в комментариях может работать, но это добавит много накладных расходов).

Другие вопросы по тегам