【问题标题】:C Extracting string between tags from a html fileC从html文件中提取标签之间的字符串
【发布时间】:2017-05-13 02:45:29
【问题描述】:

您好,我昨天从我的编程课上学习了文件 I/O,在这个练习中,我们需要从 html 文件中提取字符串并将其保存在 struct 中。

我创建了一个函数来获取字符串“Hello World”,但我的问题是我似乎无法获取第 3 次和第 4 次出现的 Hello world。如果有人可以向我解释为什么我的代码无法检测到第 3 次和第 4 次出现。

这是我的代码

void get_name (char *line, FILE * fPointer, struct Results items)
{
    char *p1;
    char *p2;
    char temp[100] = { 0 };
    int i = 0;

    while (fgets (line, 268, fPointer) != NULL) {       //String//
        p1 = strstr (line, "<span class=\"title\">");
        if (p1 == NULL) {
            printf ("Error p1\n");
        } 
        else {
            printf ("word found\n");

            p2 = strstr (p1, "</span>");

            if (p2 == NULL) {
                printf ("Error  P2\n");
            } 
            else {
                strncpy (temp, p1 + strlen ("<span class=\"title\">"),
                        p2 - p1 - strlen ("<span class=\"title\">"));
                strncpy (items[i].item_name, temp,
                        sizeof (temp) / sizeof (temp[0]));
                printf ("Success!\n");
                i++;
            }
        }
    }
}

编辑:文本

<span class="title">                                        Hello world1                            </span> 

<span class="title">Hello world2</span>                                                                 

<span class="title">                Hello world3                                                                    
</span> 


<span class="title">                                                                                        
Hello world4                                                                                        
</span>

【问题讨论】:

  • 当您的程序无法按预期运行时,正确的做法是先尝试自己调试它。通过使用调试器。你这样做了吗?你发现了什么?
  • 从记事本内容的屏幕截图中很难判断换行符在哪里。 (在使用fgets 时,这会极大地影响您对内容的搜索)请张贴实际文本(每行都以4-spaces 开头,因此格式正确)。在某些情况下,"&lt;span class=\"title\"&gt;" 甚至似乎与 Hello World 不在同一行(可能是,只是无法判断)
  • "寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身中重现它所需的最短代码。没有明确的问题陈述对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example。"
  • 您好,我发布了实际文本,我的函数似乎无法检测到另一个“Hello world”,因为 strstr 找不到“”。
  • 另外,你不应该用'\0'而不是'0'来初始化你的temp[100]吗?否则你会遇到连续使用 temp 作为字符串的问题。

标签: c string parsing


【解决方案1】:

除了 cmets 中给出的建议外,还应注意,使用 strstr 从 HTML 文档中提取数据是疯了,similar to using regex to extract HTML

很难看出这个练习的目标是什么,因为我看不出你的课程还涵盖了哪些内容。然而,鉴于结构、流、字符串和函数已被涵盖,您可能还接触过使用链接器 来链接和使用外部库。 明智地从 HTML 文档中提取数据有几个选项。其中包括:

  • libDOMgumbo-parser 和其他库将为您解析 HTML 并允许您方便地定位内容而无需重新发明 HTML 解析轮。
  • Many headless browsers,它不仅可以为您解析 HTML,还可以在没有 GUI 的情况下获取页面、提交表单、保存 cookie 和执行 Javascript。

不相信使用 saner 选项?好吧,让我们检查一下您的代码...

正如您所展示的那样,fgets 读取(最多)每次调用一行(即您的变量名,line),并且观察到您的示例(应该作为文本发布,而不是作为图像发布)包含开始标签单独一行,您的第一个调用定位第一个标签应该不足为奇,但需要进一步调用fgets 才能获取内容。即

printf ("word found\n");     // more fgets() is required between here
p2 = strstr (p1, "</span>"); // and here, because printf(line) shows us
                             // line only contains: "<span class=\"title\">\n"

这也解释了为什么您的第二个测试用例通过了(一切都在同一行)而您的第三个和第四个测试用例失败了(并非所有东西都在一行中) .要解决这个问题,显然你需要阅读多行行。

【讨论】:

  • 谢谢你,我应该试试你的建议!遗憾的是,我们仅限于使用 strstr。
  • 很遗憾,您的教授正在教您重新发明轮子并为问题制定巧妙的解决方案;对于这样的教授,我是很不信任的。尽管如此,做你需要做的事情来传递并快乐地继续前进,因为你知道你需要质疑每个练习的动机和理智。在这种情况下,动机似乎是在教你使用一个特定的功能。您是否也仅限于使用fgets,还是可以改用fread?使用fread... 甚至fscanf... 可能会更容易一些,尽管所有这些选项都疯狂...
  • 如果没有看到整个课程,我不会评判教授。在不学习一些基础知识的情况下(甚至像 strstr 这样的函数——可能是在展示了它是如何编写的之后才教授的),开始使用现成的库有不同的重点。
  • @MattAPiroglu 够公平的。不要评判教授;评判教授的...
  • 同意 100% 的疯狂评论,我认为这个问题是手动解析中的一项任务,如果这是针对现实世界的,那么是的,使用一个经过多年开发的 html 解析库而不是自己重新发明轮子……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多