c:中的文件处理无法在表格格式数据中正确读取

时间:2012-10-29 11:23:49

标签: c file-handling

#include <stdio.h>
int main(void)
{
   clrscr();
   FILE *fin;

   fin=fopen("data.txt","r");

   if(fin==NULL)
   {
    printf("can not open input fil");
    return 0;
   }

   long data[2];

   while(!feof(fin))
   {
       fscanf(fin,"%ld %ld",&data[0],&data[1]);
       printf("\n%ld %ld",data[0],data[1]);
   }
   fclose(fin);
   return;
   }

上面是我从文件中读取表格的c代码。在那个..last值打印2次!!!

data.txt
1   34
2   24
3   45
4   56
5   67

但我无法通过下面的破桌获得正确的值...我该如何解决? (这里它应该工作,它找不到任何值,它应该返回“空格”或零..但不是下一个值..)

data.txt
1   34
2   
3   45
4   
5   67

以及     data.txt中

1 34
  57
3 45
4   
5 34

2 个答案:

答案 0 :(得分:2)

  

上面是我从文件中读取表格的c代码。在那个..last值打印2次!!!

由于文件读取循环的结构,最后一个值是打印两次。在尝试读取超过文件末尾之前,不会设置eof()标志。当fscanf()从文件的最后一行long读取最后两个eof()时尚未设置,但下一次调用fscanf()失败并设置eof()但是不会立即查询fscanf()的结果,导致使用先前提取的long:立即检查所有读取操作的结果。


一种可能的解决方案是使用fgets()一次读取一行,然后使用sscanf()从读取行中提取long值。如果使用fscanf(),它将读取超过新行字符以找到第二个请求的long,这不是所需的行为。

例如:

char line[1024];
while (fgets(line, 1024, fin))
{
    /* Assign appropriate default values.
       sscanf() does not modify its arguments
       for which it has no value to assign.
       So if 'line' has a single long value
       data[1] will be zero. */
    long data[2] = { 0, 0 };

    /* You can use 'result' if you require to take particular
       action if it reads only 1, or 0, items. */
    int result = sscanf(line, "%ld %ld", &data[0], &data[1]);

    printf("\n%ld %ld",data[0],data[1]);
}

以回应问题更新)区分缺少第二个值的行:

  

2

以及缺少第一个值的行:

  

57

需要有效范围(或其他一些标准)来确定该行中缺少哪个值(第一个或第二个):

int result = sscanf(line, "%ld %ld", &data[0], &data[1]);
if (1 == result)
{
    if (data[0] >= 1 && data[0] <= 9)
    {
        printf("\n%ld 0", data[0]);
    }
    else
    {
        /* Read value was the second value. */
        printf("\n%ld %ld", ++last_first_value, data[0]);
    }
}

其中last_first_valuelong,它存储第一个值的当前值(最后一个成功读取的第一个值或从上一个成功读取的第一个值计算得出的值)。

答案 1 :(得分:0)

while(!feof(fin))
{
   fscanf(fin,"%ld %ld",&data[0],&data[1]);
   printf("\n%ld %ld",data[0],data[1]);
}

feof在您尝试读取文件末尾之后才返回true,因此循环将经常执行一次。最好检查fscanf的返回值,如果它与您的预期不匹配(在这种情况下为2),则然后检查EOF。这是一个可能的重组:

int good = 1;
while (good)
{
  int itemsRead = fscanf(fin, "%ld %ld", &data[0], &data[1]);
  if (itemsRead == 2)
  {
    // process data[0] and data[1] normally
  }
  else 
  {
    good = !good;
    if (feof(fin))
      printf("Hit end of file\n");
    else if (ferror(fin))
      printf("Error during read\n");
    else
      printf("Malformed input line\n");
  }
}