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

时间:2012-06-15 13:31:33

标签: c linux file file-io

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");

我已经为以下目的编写了上述C代码:

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

    1. mailer.txt复制到tempmailer.txt所有行,无论给出任何条件(不受欢迎)
    2. 删除mailer.txt并创建新的mailer.txt(所需)
    3. tempmailer.txt复制到新文件(所需)
    4. 删除tempmailer.txt(所需)
    5. 无论我做什么,我都无法根除这个问题。操作系统是linux。请帮我。提前谢谢。

5 个答案:

答案 0 :(得分:2)

你需要在第二个while循环之前寻找文件的开头。

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

答案 1 :(得分:2)

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

while(fgets(line, sizeof line, mails) != NULL)
{
    int flag=0;
    rewind(tempmails);                              /* go back to the begining */
    while(fgets(templine, sizeof line, tempmails) != NULL)
    {
        /* ... */
    }
}

答案 2 :(得分:1)

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

这可以通过简单的shell脚本解决,你真的必须用C写吗?

答案 3 :(得分:1)

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

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);             
    }       
}         

如果程序找到一条使if条件成为真的行,则该标志设置为1,但如果条件为真,则下一行可能不生成,并且您的程序无法将该标志设置为0.因此,您永远不会将该标志设置为0。不匹配的行在匹配的行之后进入电子邮件。

答案 4 :(得分:0)

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

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

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");

现在你至少可以知道它是否可以打开和读取文件。要检查fgets是否有效,并且没有给您错误,请使用ferrorfeof

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