0
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

但是在运行时实际发生的是:

  1. 无论给定的任何条件如何,都从所有行复制(不希望mailer.txt的)tempmailer.txt
  2. 删除mailer.txt并创建一个新的mailer.txt(期望的)
  3. 从原样复制tempmailer.txt到新文件(需要)
  4. 删除tempmailer.txt(需要)

无论我做什么,我都无法根除这个问题。操作系统是linux。请帮我。提前致谢。

4

5 回答 5

2

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

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

于 2012-06-15T13:44:17.970 回答
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)
    {
        /* ... */
    }
}
于 2012-06-15T13:55:29.933 回答
1

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

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

于 2012-06-15T13:37:23.173 回答
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,但下一行可能不会使 if 条件为真,并且您的程序不能将标志设置为 0。因此,您永远不会放置不匹配的行在匹配行之后进入临时邮件。

于 2012-06-15T13:54:04.720 回答
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

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

于 2012-06-15T13:38:33.563 回答