C 删除<;img></img>;标签

C 删除<;img></img>;标签,c,string,getline,C,String,Getline,我有这个密码。代码的目的是打印之前的所有内容和之后的所有内容。不应打印和之间的所有内容。然而,我有两个问题 代码是在windows(gcc编译器)上编译的,但当我运行它时,它只是说“程序停止工作了” 代码正在打印所有内容。它甚至正在打印, 以及介于两者之间的所有内容 我的#包括: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #incl

我有这个密码。代码的目的是打印
之前的所有内容和
之后的所有内容。不应打印
之间的所有内容。然而,我有两个问题

  • 代码是在windows(gcc编译器)上编译的,但当我运行它时,它只是说“程序停止工作了”
  • 代码正在打印所有内容。它甚至正在打印
    以及介于两者之间的所有内容
  • 我的#包括:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <unistd.h>
    
    #包括
    #包括
    #包括
    #包括
    #包括
    
    代码:

    void replacer_和_打印(文件*fp){
    字符*行;
    尺寸透镜;
    阅读;
    bool found_tag=false;
    内线仓库;
    字符*在标签前;
    标签后面的字符*;
    while((read=getline(&line,&len,fp))!=-1){
    如果(
    (_tag=strstrstr(第,“”)行之前)!=NULL)&&
    (_tag=strstrstr(第行,“”)之后)!=NULL)
    ) {   
    行\u storer=前\u标记-行;
    printf(“%s”,第行,第行);
    printf(“用于此处的图像\n”);
    行\u storer=在\u标记后-行+strlen(“”);
    printf(“%s”,行+行存储器);
    }如果((在标签=strstrstr(行,“”)之前)!=NULL,则为else{
    行\u storer=前\u标记-行;
    printf(“%s”,第行,第行);
    found_tag=true;
    }如果((在标签=strstr(行,“”)之后)!=NULL){
    发现标签=假;
    行\u storer=在\u标记后-行+strlen(“”);
    printf(“%s”,行+行存储器);
    }如果(!found_tag){
    printf(“%s”,第行);
    }
    }
    fclose(fp);
    }
    

    test.html:

    <b>This is a test page</b>
    <div class=back1>Some more text here for more testing!!!!</div>
    <img>www.website.com/image.png</img>
    <i>More words</i>
    <u><i><b>TESTING 123</u></i></b>
    
    这是一个测试页面
    这里有更多的文字供更多测试!!!!
    www.website.com/image.png
    更多的话
    测试123
    

    输出:

    <b>This is a test page</b>
    <div class=back1>Some more text here for more testing!!!!</div>
    The Image use to be here
    <i>More words</i>
    <u><i><b>TESTING 123</u></i></b>
    
    这是一个测试页面
    这里有更多的文字供更多测试!!!!
    这张照片曾经在这里
    更多的话
    测试123
    

    假设:

    There will only be one <img>
    There will only be one </img>. The </img> tag will always be after the <img>
    
    将只有一个
    只有一个。标签将始终位于
    
    在第一次调用
    getline()
    之前,需要设置
    len=0

    getline
    的手册页

    如果在调用之前*lineptr设置为NULL且*n设置为0,则getline()将分配一个缓冲区来存储该行。即使getline()失败,用户程序也应释放此缓冲区

    len
    是堆栈分配的-因此除非初始化它,否则它可以包含任何值

    此外,在完成之前,您应该是
    free()
    ing
    line

    free(line);
    fclose(fp);
    
    最后,您应该检查
    fopen()
    中的返回值

    getline()
    和Windows 我怀疑您在Windows上遇到的问题是因为Windows没有实现
    getline()
    函数。(它不是C标准的一部分-它是一个POSIX函数。)

    您也可以尝试使用
    fgets()
    。下面的例子

    N.B.注意,在这种情况下,
    的内存不是动态分配的

    char line[128] = {'\0'};
    
    while (fgets(line, sizeof(line), fp) != NULL) {
    // etc..
    }
    // Do NOT call free(line) at end of scope in this case!
    

    您的代码中存在多个问题:

    • 必须初始化为
      NULL
      len
      0
      。在没有初始化的情况下,由于
      line
      len
      具有自动存储(也称为堆栈上),因此代码具有未定义的行为,在您的情况下会导致提前终止
    • HTML
    您做出了一些不必要的假设,实际上会使代码复杂化: *每行仅删除第一个图像。 *如果
    标记和
    位于不同的行上,则可能会有一个关闭标记出现在不相关的打开标记之前的同一行上。您的第一个测试将被这种情况所愚弄,并产生不正确的输出

    以下是带有嵌套循环的更正版本:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <unistd.h>
    
    int main() {
        FILE *fp;
        char *line, *p, *q;
        size_t len;
        bool found_tag;
    
        fp = fopen("test.html", "r");
        if (fp == NULL) {
            fprintf(stderr, "cannot open %s\n", "test.html");
            return 1;
        }
    
        line = NULL;
        len = 0;
        found_tag = false;
        while (getline(&line, &len, fp) != -1) {
            for (p = line;;) {
                if (found_tag) {
                    q = strstr(p, "</img>");
                    if (q == NULL) {
                        /* skip the rest of the line */
                        break;
                    }
                    found_tag = false;
                    p = q + strlen("</img>");
                } else {
                    q = strstr(p, "<img");
                    if (q == NULL) {
                        fputs(p, stdout);
                        break;
                    }
                    printf("%.*s%s", (int)(q - p), p,
                           "The Image used to be here\n");
                    found_tag = true;
                    p = q + strlen("<img");
                }
            }           
        }
        free(line);
        fclose(fp);
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    int main(){
    文件*fp;
    字符*行,*p,*q;
    尺寸透镜;
    布尔找到了标签;
    fp=fopen(“test.html”,“r”);
    如果(fp==NULL){
    fprintf(stderr,“无法打开%s\n”,“test.html”);
    返回1;
    }
    行=空;
    len=0;
    发现标签=假;
    while(getline(&line,&len,fp)!=-1){
    对于(p=line;;){
    如果(找到标签){
    q=strstr(p,“”);
    if(q==NULL){
    /*跳过剩下的部分*/
    打破
    }
    发现标签=假;
    p=q+strlen(“”);
    }否则{
    
    q=strstr(p),“欢迎来到StackOverflow!在大多数情况下,这是一篇很好的第一篇文章;但是,你应该在文章中包含任何你不会帮助解决的错误。你声明代码不会在Windows上编译,你能包含编译器错误吗?”“@c1moore一点也没有错误。它编译得很好。但是,当我运行它时,它只是停止工作,那么为什么你在帖子中包含了#1?”很抱歉,@c1moore的措辞是错误的。编辑了帖子提示:当输出有问题时,用哨兵包围字符串输出,如
    ,并在每个输出结束时使用
    \n
    。它最好暴露过多的白色。”-空格、换行、回车问题。例如
    printf(“%s”,行存储器,行);
    -->
    printf(“\n”,行存储器,行)
    添加了这两个内容,仍然没有打印任何内容,但现在它至少没有崩溃。由于某种原因,它不符合while循环条件。因此它不会进入while循环。@SarahChan:在你的问题中,你说“代码正在打印所有内容”“。现在你说的正好相反。你能澄清一下吗?@SarahChan:我没有访问
    mingw
    或Windows计算机的权限。但是,你确定文件被正确打开了吗?我问你,因为你没有检查
    fopen()的返回值。”
    @SarahChan:如果您还没有这样做,我认为现在是使用调试器的好时机(我认为
    mingw
    提供了
    gdb
    )。
    if (!fp) {
        perror("fopen");
        // Handle error and return if appropriate
    }
    
    char line[128] = {'\0'};
    
    while (fgets(line, sizeof(line), fp) != NULL) {
    // etc..
    }
    // Do NOT call free(line) at end of scope in this case!
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <unistd.h>
    
    int main() {
        FILE *fp;
        char *line, *p, *q;
        size_t len;
        bool found_tag;
    
        fp = fopen("test.html", "r");
        if (fp == NULL) {
            fprintf(stderr, "cannot open %s\n", "test.html");
            return 1;
        }
    
        line = NULL;
        len = 0;
        found_tag = false;
        while (getline(&line, &len, fp) != -1) {
            for (p = line;;) {
                if (found_tag) {
                    q = strstr(p, "</img>");
                    if (q == NULL) {
                        /* skip the rest of the line */
                        break;
                    }
                    found_tag = false;
                    p = q + strlen("</img>");
                } else {
                    q = strstr(p, "<img");
                    if (q == NULL) {
                        fputs(p, stdout);
                        break;
                    }
                    printf("%.*s%s", (int)(q - p), p,
                           "The Image used to be here\n");
                    found_tag = true;
                    p = q + strlen("<img");
                }
            }           
        }
        free(line);
        fclose(fp);
        return 0;
    }