2015-05-03 74 views
2

我想知道如何循环我做的解析器。我有几个文本文件,我不知道该怎么做。这是代码。循环解析器

#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> 

我的代码只解析第一项。我是一个新手,所以引导我。谢谢。

+7

那么,一个,你的标题说“循环”。这几乎涉及所有情况......一个*循环*。尝试一个? – WhozCraig

+0

我不知道该把它放在哪里:(还有条件 – estudyante

+1

我希望为了你自己的缘故,你正在把解析器当做学习练习,因为像你这样的标记文件的解析器已经存在。只不过是简化的XML,这意味着几乎任何XML解析器都应该能够处理它 –

回答

1

它看起来像所有你需要做的是将您的if更改为while,并保持指针在你走的时候在字符串中移动。我相信改变

if(start = strstr(file_contents, tag1)) 

start = file_contents; 
while(start = strstr(start, tag1)) 

会得到你想要的行为(假设代码工作的其余部分)。只要你仍然从剩余的字符串(从start开始)得到strstr的非NULL返回,它就会继续循环。

正如我在我的评论中提到的,我还建议您查看递归解析,如果你想要的话;它似乎对您的情况会很好(免责声明:我不是解析器专家)。除此之外,你的代码看起来不错,特别是对于一个自称的新手!


编辑:看来,你的代码需要一点调整,至少得到它的循环,我的建议去做。您应该避免复制字符串,只需以“嵌套”的方式遍历它。只是重新安排你的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可能工作,但这会增加很多开销)。

+0

它变成了一个无限循环,我应该将'end'复制到'file_contents'中吗?或者这是一个坏主意?我正在考虑把'strcpy(file_contents,end);'... – estudyante

+0

I w这有点误会你是如何在输入过程中走过的。看起来您正在寻找''和''标签,复制它们之间的任何内容,然后在您的新副本中查找嵌入式标签。这不仅意味着我的代码错了,但我不知道这是一个好策略。在我看来,你应该找到''标签,用它作为查找嵌入式标签的起点,然后找到嵌入式关闭标志(打印出它们之间的标志),然后找到你的''标签;所有这些都在你的文件字符串中(使用'start'来跟踪) – sabreitweiser

+0

我将编辑我的答案以向你展示我的意思。 – sabreitweiser