文件处理程序在C中未按预期工作

文件处理程序在C中未按预期工作,c,linux,file,file-io,C,Linux,File,File Io,我编写上述C代码的目的如下: 必须读取mailer.txt中的每一行,检查一行是否为空或重复,如果两个条件都为假,则必须将其输入临时文件tempmailer.txt 删除文件mailer.txt,然后创建一个新文件并将其逐个复制到新文件中,然后删除tempmailer.txt 但在运行时,实际发生的是: 从mailer.txt复制到tempmailer.txt所有行,而不考虑给定的任何条件(不需要) 删除mailer.txt并创建一个新的mailer.txt(需要) 从tempmailer.tx

我编写上述C代码的目的如下:

  • 必须读取
    mailer.txt
    中的每一行,检查一行是否为空或重复,如果两个条件都为假,则必须将其输入临时文件
    tempmailer.txt
  • 删除文件
    mailer.txt
    ,然后创建一个新文件并将其逐个复制到新文件中,然后删除
    tempmailer.txt
  • 但在运行时,实际发生的是:

  • mailer.txt
    复制到
    tempmailer.txt
    所有行,而不考虑给定的任何条件(不需要)
  • 删除
    mailer.txt
    并创建一个新的
    mailer.txt
    (需要)
  • tempmailer.txt
    复制到新文件(需要)
  • 删除
    tempmailer.txt
    (需要)

  • 无论我做什么,我都不能证明这个问题。操作系统是linux。请帮帮我。提前感谢。

    重复检测代码非常奇怪,它同时从两个文件中读取。无法从为追加而打开的文件中读取。尝试模式
    a+


    这可以通过一个简单的shell脚本来解决,您真的必须用C编写吗?

    重复检测代码非常奇怪,它同时从两个文件中读取。无法从为追加而打开的文件中读取。尝试模式
    a+

    这可以通过一个简单的shell脚本来解决,您真的必须用C编写它吗?

    免责声明:这不是一个真正的答案,但肯定有助于调试

    在以下几行之后,您应该检查指针是否为NULL:

    FILE *mails;
    FILE *tempmails;
    mails = fopen("mailer.txt", "r");
    tempmails = fopen ("tempmailer.txt" , "a+");
    char line[200],templine[200];
    char blnklne[]="\n";        
    while(fgets(line, sizeof line, mails) != NULL)
    {       
        int flag=0;    
        while(fgets(templine, sizeof line, tempmails) != NULL)
        {               
            if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
            {               
                flag = 1;               
            }               
        }           
        if(flag == 0)
        {           
            fputs(line, tempmails);             
        }       
    }       
    fclose(mails);
    fclose(tempmails);
    tempmails = fopen ("tempmailer.txt", "r");
    remove("mailer.txt");
    FILE *newmails;
    newmails = fopen("mailer.txt", "a");
    while(fgets(templine, sizeof line, tempmails) != NULL)
    {       
        fputs(templine, newmails);      
    }       
    fclose(newmails);
    fclose(tempmails);
    remove("tempmailer.txt");
    
    现在您至少可以知道它是否可以打开和读取文件。要检查
    fgets
    是否工作,并且不会给您带来错误,请使用
    ferror
    feof

    每次在文件句柄上调用
    fopen
    时,都应该添加相同的空检查。

    免责声明:这不是真正的答案,但肯定有助于调试

    在以下几行之后,您应该检查指针是否为NULL:

    FILE *mails;
    FILE *tempmails;
    mails = fopen("mailer.txt", "r");
    tempmails = fopen ("tempmailer.txt" , "a+");
    char line[200],templine[200];
    char blnklne[]="\n";        
    while(fgets(line, sizeof line, mails) != NULL)
    {       
        int flag=0;    
        while(fgets(templine, sizeof line, tempmails) != NULL)
        {               
            if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
            {               
                flag = 1;               
            }               
        }           
        if(flag == 0)
        {           
            fputs(line, tempmails);             
        }       
    }       
    fclose(mails);
    fclose(tempmails);
    tempmails = fopen ("tempmailer.txt", "r");
    remove("mailer.txt");
    FILE *newmails;
    newmails = fopen("mailer.txt", "a");
    while(fgets(templine, sizeof line, tempmails) != NULL)
    {       
        fputs(templine, newmails);      
    }       
    fclose(newmails);
    fclose(tempmails);
    remove("tempmailer.txt");
    
    现在您至少可以知道它是否可以打开和读取文件。要检查
    fgets
    是否工作,并且不会给您带来错误,请使用
    ferror
    feof


    每次在文件句柄上调用
    fopen
    时,都应该添加相同的空检查。

    在第二个while循环之前,需要查找文件的开头


    目前,您的第二个while循环将永远找不到任何匹配的行,因为它始终指向文件的结尾。

    您需要在第二个while循环之前查找文件的开头


    目前,您的第二个while循环将永远找不到任何匹配的行,因为它总是指向文件的末尾。

    也许这部分代码就是您得到问题1的原因

    mails = fopen("mailer.txt", "r");
    tempmails = fopen ("tempmailer.txt" , "a+");
    
    if (mails == NULL) printf("Error: could not open file");
    if (tempmails == NULL) printf("Error: could not open file");
    

    如果程序找到一行使If条件为真,则标志设置为1,但下一行可能不使If条件为真,您的程序无法将标志设置为0。因此,您永远不会将匹配行后面的不匹配行放入tempmails中。

    也许这部分代码就是您得到问题1的原因

    mails = fopen("mailer.txt", "r");
    tempmails = fopen ("tempmailer.txt" , "a+");
    
    if (mails == NULL) printf("Error: could not open file");
    if (tempmails == NULL) printf("Error: could not open file");
    

    如果程序找到一行使If条件为真,则标志设置为1,但下一行可能不使If条件为真,并且您的程序不能将标志设置为0。因此,您永远不会将匹配行后面的不匹配行放入tempmails中。

    在开始每个第二个循环之前,将
    tempmails
    重置到文件的开头

    while(fgets(line, sizeof line, mails) != NULL)
    {       
         int flag=0;    
         while(fgets(templine, sizeof line, tempmails) != NULL)
        {               
            if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
           {               
                flag = 1;               /* this part may be not correct */
            }               
        }           
        if(flag == 0)
        {           
            fputs(line, tempmails);             
        }       
    }         
    

    在开始每个第二个循环之前,将
    tempmails
    重置到文件的开头

    while(fgets(line, sizeof line, mails) != NULL)
    {       
         int flag=0;    
         while(fgets(templine, sizeof line, tempmails) != NULL)
        {               
            if((strcmp(line,templine)==0) || (strcmp(line,blnklne)==0))
           {               
                flag = 1;               /* this part may be not correct */
            }               
        }           
        if(flag == 0)
        {           
            fputs(line, tempmails);             
        }       
    }         
    

    请缩进你的代码,它几乎不可读!为什么您要将tempmailer.txt中的每一行的
    (来自mailer.txt)与空行进行比较?请缩进您的代码,它几乎不可读!为什么要将tempmailer.txt中的每一行的
    (来自mailer.txt)与空行进行比较?这两个文件都已成功打开。否则,读写是如何发生的?只有条件不满足。两个文件都已成功打开。否则,读写是如何发生的?只有条件不满足。我用过的是
    a+
    ,不是
    a
    。我用过的是
    a+
    ,不是
    a
    。oops。。我不是有意删除的!当标志设置为1时,也需要中断,以避免丢失duplicates@JonCage:断开“仅”可防止执行额外的不必要的工作:设置
    标志后未能断开不会生成错误的结果。Ooops。。我不是有意删除的!当标志设置为1时,也需要中断,以避免丢失duplicates@JonCage:打破“仅限”防止额外的不必要的工作被完成:设置
    标志后未能中断不会产生错误的结果。+1取消删除答案:我认为你可能在改进答案,并在发布我的答案之前等待了一段时间。+1取消删除答案:我认为你可能在改进答案,并在发布我的答案之前等待了一段时间。