【问题标题】:Extracting Pure Text from an HTML File从 HTML 文件中提取纯文本
【发布时间】:2013-03-12 21:31:26
【问题描述】:

美好的一天,我希望你能帮助我。我必须编写这段代码(用 C 语言)来下载网站的页面源并将其保存到 html 文件中(我已经这样做了)。下一部分是使用保存的 html 文件从该站点提取文本。

我脑子里有这个算法步骤:

假设我们有一个包含以下内容的 html 文件:

你好再见!

  1. 查找“”字符串,跳过“”字符串。 (这可以用 strstr() 来实现)
  2. 将指针设置为“”的第一个“>”。 (使用 strchr()??)
  3. 检查字符串中的下一个字符是否为“”。重复检查 (3)。 b.) 如果否,则获取字符串直到下一个“
  4. 最后,我想将字符串保存到 file.txt。 (fwite?或 fopen() 中的选项 a+)。

从逻辑上讲,这是正确的,对吧? 作为编程的初学者,我总是会出错。我写了一段代码,但总是导致分段错误。

请帮助我/告诉我我的代码有什么问题: Dummy - 包含 html 代码的文件

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <time.h>

    int get_fileSize(FILE*);

    int main(){

        FILE *dummy = fopen("Dummy2","r");

        int filesize = get_fileSize(dummy);
        printf("Size of dummy = %d Bytes.\n", filesize);

        char *newString = (char*)malloc((sizeof(char*))*(filesize));

        if(dummy){
            fread(newString, sizeof(char*), filesize, dummy);
        }   

        char *tempString = (char*)malloc((sizeof(char*))*(filesize));
        char *finalString = (char*)malloc((sizeof(char*))*(filesize));
        finalString = "\0";

        tempString = strtok(newString, "<");
        do{

            //printf("%s\n",tempString);
            tempString = strtok(NULL, ">");

            if(tempString[1]!='<'){
                    sprintf(finalString,"%s%s",finalString,tempString);            
            }else continue;

        }while(*(newString++)!='\0');

        puts(finalString);

        return 0;
    }

    int get_fileSize(FILE *dummy){

        int size;
        struct stat file;
        fstat(fileno(dummy), &file);
        size = file.st_size;

        return size;

    }

【问题讨论】:

  • 不简单地解析 HTML
  • 您要提取的 HTML 元素到底是什么?为什么不使用可以解析 HTML/XML 的库?
  • @MichaelFoukarakis,先生,我尽可能不想使用这些库。我还在学习 C 语言,我被指示先用经典方法来学习。
  • “经典方式”是使用标准库(即不第二次实现轮子)。另一种选择是浏览标准库,提取接口,并为自己实现主体作为学习的问题。您应该始终戴上标有“系统开发人员”或“应用程序开发人员”的帽子,并区分两者,不要混用。
  • 您应该考虑更改问题的名称以说明您希望在没有库的情况下实现它。这是一个常见的问题,但你想要一个不常见的答案。

标签: c parsing


【解决方案1】:

第一眼看你的代码,第一个错误是你做了sizeof(char*) 而不是char

char *newString = (char*)malloc((sizeof(char*))*(filesize));

应该是

char *newString = (char*)malloc((sizeof(char))*(filesize));

您不希望字符串中有指针,而是 chars。

你上面的malloc,从不打电话给free(newString),这意味着你至少有1个泄漏,可能更多。

这里也一样:

fread(newString, sizeof(char*), filesize, dummy);

应该是:

fread(newString, sizeof(char), filesize, dummy);


finalString = "\n"; //reassigns the pointer to another string, doesn't write into allocated memory.  

使用strcpy 将字符串复制到分配的内存中。

【讨论】:

  • 谢谢您,先生!我会注意这一点。稍后我会在 Ubuntu 中编写代码时尝试一下。我现在在 Windows 中。
  • 从技术上讲,两者都不会导致段错误:char* 大于 char,因此分配了更多内存。此外,您无法阅读超出 eof 的内容,因此 fread 也是合法的。不过,代码中还有其他错误。
【解决方案2】:

您的代码中有一些错误,这些错误比 Tony The Lion 的回答中提到的更严重。考虑一下:

    char *tempString = (char*)malloc((sizeof(char*))*(filesize));
    char *finalString = (char*)malloc((sizeof(char*))*(filesize));
    finalString = "\0";
    tempString = strtok(newString, "<");

最后两行有效地使前两行无用。您将常量字符串重新分配给变量。然后,当您将 sprintf 转到 finalString 时,您会收到一个 sig 错误,因为字符串是常量(并且存储在具有预定义大小 - 1 个字符的静态内存中)。

我建议使用一些标准的解析库。您必须注意,HTML 并不总是格式正确,允许嵌套标签,必须忽略某些文本(例如 scriptstyle 标签内等)。

如果你仍然想自己做,你最好遍历输入,跟踪你是在标签内,跳过这些字符,还是在纯文本内,将此文本添加到你的 finalString 之类的东西中。

【讨论】:

    【解决方案3】:

    如果您正在获取文件大小,请使用它来控制循环(读取文件并不能保证您读取的内容末尾会有一个零字节):

    for (toggle = 0, i = 0; i < filesize; ++i) {
          if      (filearray[ i ] == '<')                toggle = 1;
          else if (filearray[ i ] == '>' && toggle != 0) toggle = 0;
          else if (!toggle) {
               printf("\nText char '%c' at %d", filearray[ i ], i);
          }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 2019-10-21
      • 2011-10-09
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多