【问题标题】:C program to merge files not finding EOF, stuck in infinite loop!C程序合并文件找不到EOF,陷入无限循环!
【发布时间】:2011-04-09 13:24:09
【问题描述】:

我在尝试运行我正在开发的这个程序时遇到了一些问题......要求说我不允许使用排序功能......我自己做了一些事情......等等。

差不多,程序编译但执行后挂起......我猜它陷入了无限循环......但我似乎找不到它...... :(

这个程序读取已经按从小到大排序的数据文件,并将它们合并(排序)到第三个 .txt 文件中...

这两个文件是Data1.txt和Data2.txt 包含:

Data1.txt

2
2
2
2

Data2.txt

1
3
5
7
9

结合.c

#include <stdio.h>
#include <stdlib.h>


void sortData(FILE *fpData1, FILE *fpData2)
{

 int n, m; 
 FILE *fpMerge;


 fpMerge = fopen("Merge.txt", "w+");


 fscanf(fpData2, "%i", &n);
 fscanf(fpData1, "%i", &m);
 while(n != EOF || m != EOF)
 {

  if(n == EOF)
  {
   fscanf(fpData1, "%i", &m);

   while(m != EOF)
   {

    fprintf(fpMerge, "%i\n", m);
    fscanf(fpData1, "%i", &m);
   }
  }
  if(m == EOF)
  {
   fscanf(fpData2, "%i", &n);

   while(n != EOF)
   {

    fprintf(fpMerge, "%i\n", n);
    fscanf(fpData2, "%i", &n);
   }

  }

  if(n < m)
  {
   fprintf(fpMerge, "%i\n", n);
   fscanf(fpData2, "%i", &n);
  }
  if(n > m)
  {
   fprintf(fpMerge, "%i\n", m);
   fscanf(fpData1, "%i", &m);
  }
  if(n == m)
  {
   fprintf(fpMerge, "%i\n", n); 
   fprintf(fpMerge, "%i\n", m);
   fscanf(fpData2, "%i", &n);
   fscanf(fpData1, "%i", &m);

  }
 }

 fclose(fpMerge);
}

int main (void)
{
 FILE *fpData1;
 FILE *fpData2;


 fpData1 = fopen("Data1.txt", "r");
 if(fpData1 == NULL)
 {
  printf("There was an error opening the file...program terminating..\n");
  exit(1);
 }

 fpData2 = fopen("Data2.txt", "r");
 if(fpData2 == NULL)
 {
  printf("There was an error opening the file...program terminating..\n");
  exit(1);
 }



 sortData(fpData1, fpData2);


 fclose(fpData1);
 fclose(fpData2); 

 return 0;
}

【问题讨论】:

  • "...我猜是..." 您是否附加了一个调试器来查看您的程序在做什么?您是否尝试过添加一些适当的调试输出语句(使用printf)来查看哪里出错了?
  • 我添加了一些 printf,似乎程序没有在文件中移动...它停留在第一个数字并且永远存在...有没有更好的方法来移动指针...因为我真的不确定......我之前用 fscanf 做过我没有看到我做错了什么......

标签: c algorithm programming-languages file-io loops


【解决方案1】:

你不想比较n != EOF,而是fscanf的返回值:

int count_1;
count_1 = fscanf(fpData1, "%i", &m);
if (count_1 == EOF) // EOF (or error)
{
  // ...
}

fscanf 也会在出错时返回 EOF。如果您需要区分 EOF 和错误条件,请使用 ferror(fpData1),例如,然后查找错误代码(存储在 errno 中)。

【讨论】:

  • 那我可以使用 (!feof(filename)) 吗?我开始使用它...但我尝试将其更改为 != EOF 以查看它是否有所作为...但它没有..
  • 我的手册页没有提到 fscanf() 设置流 eof 标志(feof() 测试)。为什么不抓取返回值,测试一下是不是EOF?
  • 我发现了我的问题.. 我讨厌我的循环有点搞砸了检查错误的 EOF。无论如何谢谢:)
【解决方案2】:

您对 EOF 的测试不太正确

void sortData(FILE *fpData1, FILE *fpData2)
{
    int data1;
    int data2; 
    FILE *fpMerge;

    fpMerge = fopen("Merge.txt", "w+");
    fscanf(fpData1, "%i", &data1);
    fscanf(fpData2, "%i", &data2);

    // While one file still has data        
    while(!feof(fpData1) && !feof(fpData2))
    {
        // Choose 1 file to test
        // Read from that file and put into merge file until either we
        // run out of data or the condition fails.
        if(data1 < data2)
        {
            do {fprintf(fpMerge, "%i\n", data1);}
            while ((fscanf(fpData1, "%i", &data1) != 0) && (data1 <= data2));
        }
        else
        {
            do {fprintf(fpMerge, "%i\n", data2);}
            while ((fscanf(fpData2, "%i", &data2) != 0) && (data2 <= data1));
        }
        // NOTE: if fscanf() returns 0 it has failed to read (EOF)
    }
    // One of the files has reached the EOF
    // Dump the other file.
    while(fscanf(fpData1, "%i", &data1) != 0) {fprintf(fpMerge, "%i\n", data1);}
    while(fscanf(fpData2, "%i", &data2) != 0) {fprintf(fpMerge, "%i\n", data2);}
}

【讨论】:

    【解决方案3】:

    EOF 不是字符。
    EOF 不是整数。
    任何文件都不会有 EOF(char 和 int 都没有)。

    EOF 是一个条件。
    文件将处于该条件或(通常)不是。

    您应该检查fscanf()的返回值以检测EOF或其他问题。

    【讨论】:

    • EOF 是一个整数(或至少可转换为一):它由int fscanf(FILE *stream, const char *format, ...) 返回。我的stdio.h 副本(我认为来自eglibc)#define s EOF 为-1。更好的说法是:“如果您将fscanf() 放入一个变量并对照EOF 进行检查,那么您并没有做您认为您正在做的事情。您将从文件中读取的值与您的版本进行比较的stdio.h 用来表示EOF,这几乎肯定不是你想要的。”
    • 是的,我的文字有点太强了。谢谢指正。
    • 是的...EOF 是一个整数,而char unsigned 值是int 的子集,与这些f* stdio 函数中使用的唯一条件值EOF 不相交。
    猜你喜欢
    • 2016-07-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    相关资源
    最近更新 更多