如何将c中的整个文件读入数字数组

时间:2014-01-09 13:43:55

标签: c arrays memory-management file-io

我正在用C语言编写一个程序,它应该从任意长度的文件中读取双精度数组。如何在EOF停止?我尝试过使用feof,但随后阅读了讨论内容:

Why is “while ( !feof (file) )” always wrong?

How does C handle EOF?

然后他们再次关注字符串,而不是数字。因此,当读取“4 23.3 2 1.2”形式的文件时,如何声明循环条件,以便我的数组A包含文件中的所有数字而已(仅迭代器N = A的长度)?

这是我的代码中使用feof的部分,它在A中产生了太多的条目。重新分配部分基于http://www.cplusplus.com/reference/cstdlib/realloc/示例。

int N = 0;    

double *A = NULL;
double *more_space;
double buff = 0;

FILE *data;
data = fopen(data.dat,"r");

while(feof(data) == 0) {
    fscanf(data, "%lg", &buff);
    more_space = realloc(A, (N+1)*sizeof(double));
    A = more_space;
    A[N] = buff;
    N++;
}

5 个答案:

答案 0 :(得分:1)

fscanf告诉您没有更多数据需要阅读时,请停止。它的返回值表示它读取的项目数,如果到达文件末尾或读取错误,则返回EOF。因此,由于您在每次通话中只阅读一个项目,只要阅读成功,您就会获得1个。

while (fscanf(data, "%lg", &buff) == 1) {
    ...
}

您可能希望将返回值存储在变量中,以验证是否因文件结束或双解析失败而停止读取。

答案 1 :(得分:1)

当你遇到eof(或其他问题)时,fscanf的返回值为-1,因此请尝试while(fscanf(…) >= 0)作为外部循环。 (您是否接受零返回值取决于您希望如何处理错误数据 - 正如其他海报所指出的那样,如果没有转换数字,您将获得0。

我喜欢使用'大于或等于'测试(而不是测试==1),因为如果你将scanf格式更改为,例如,从输入行读取两个项目,它就不会中断。另一方面,你可以争辩说,最好确定你总是读出正确数量的参数,并且一旦你改变了少数参数的数量,你的程序“快速失败”就好了。如果你得到不好的输入,后来的神秘失败。这是一个风格问题,这是一个分配或生产代码的一次性代码..

答案 2 :(得分:1)

在扫描期间,保存fscanf()

的结果
int cnt;
double d;
while ((cnt = fscanf("%f", &d)) == 1) {
  more_space = realloc(A, (N+1)*sizeof(double));
  if (more_space == NULL) Handle_MemoryError();
  A = more_space;
  A[N] = buff;
  N++;
}
if (cnt == 0) Handle_BadDataError();

答案 3 :(得分:0)

你应该这样做:

while (fscanf(data, "%lg", &buff) == 1)

这样,如果你点击“非数字”,那么它将停止而不是无限循环!! ......并且fscanf会检查EOF,它会为你打破循环。

答案 4 :(得分:0)

除其他答案外,请阅读整个文件:

int32_t readFile ( char* filename, uint8_t** contentPtr, int32_t* sizePtr)
{
  int32_t ret = 0;
  struct stat st;
  FILE *file = NULL;
  uint8_t* content = NULL;

  memset ( &st, 0, sizeof ( struct stat ) );

  ret = stat( filename, &st );
  if( ret < 0 ) {
     return -1;
  }

  file = fopen64(filename, "rb");
  if ( file == NULL ) {
    return -1;
  }

  content = calloc ( st.st_size+10, sizeof ( uint8_t ) );

  ret = fread ( content, 1, st.st_size, file );
  fclose( file );
  if( ret != st.st_size ) {
    free(content);

    return -1;
  }

  *contentPtr = content;
  if (sizePtr != NULL) {
    *sizePtr = st.st_size;
  }

  return 0;
}

然后使用sscanf()处理缓冲区的内容。

相关问题