如何从未指定的文件大小读取值并将它们动态存储在C中的向量中?

时间:2016-07-24 17:31:49

标签: c algorithm file pointers vector

说我有一个numbers.txt文件,其中包含未指定大小的数字。

我需要将这些值动态存储在double *note指针中以供以后使用。

我尝试了以下代码,但它提供了核心转储:

FILE *ifile = fopen("numbers.txt", "r");
double *note;
int i = 1; 

note = (double *) malloc( i * sizeof( double));
fscanf( ifile, "%lf", &note[0]); 

while ( !feof( ifile)) {
      i++;
      note = (double *) realloc( note, i * sizeof( double));
      fscanf( ifile, "%lf", &note[i]);
}       

for (n=0; n < i; n++) {
     printf( "%lf\n", note[i]);
}

2 个答案:

答案 0 :(得分:1)

每次使用note[i]时,您的代码都会从其边界外访问数组。

在(wrong)while循环中,它总是超过最后一个元素(例如,在第一次迭代i中变为2,分配了足够的空间用于两个double s,但是你访问第三个note[2]

打印时,您使用n作为增加循环索引,但始终打印note[i]而不是note[n]

检查所有使用的库函数的返回值也是一种很好的做法,例如opennewreallocscanf

这些问题的快速解决方法可能是以下代码段。请注意,我使用了与您相同的重新分配策略(每次),但正如@Serge Ballesta指出的那样,这可能效率低下。例如,请看@ Jean-FrançoisFabre的答案。

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

int main() {
    double value,
           *note = NULL,
           *newptr = NULL;

    int i,
        size = 0;

    char file_name[] = "numbers.txt";
    FILE *ifile = fopen(file_name, "r");
    if ( !ifile ) {
        fprintf(stderr, "Error while opening file %s.\n", file_name);
        exit(EXIT_FAILURE);
    }

    while ( fscanf(ifile, "%lf", &value) == 1 ) {
        size++;
        newptr = realloc(note, size * sizeof(double));
        if ( !newptr ) {
            fprintf(stderr, "Error while reallocating memory.\n");
            free(note);
            exit(EXIT_FAILURE);
        }
        note = newptr;
        note[size - 1] = value;
    }       

    for (i=0; i < size; i++) {
        printf( "%lf\n", note[i]);
    }

    free(note);     // <-- don't leak memory!
    fclose(ifile);
    return EXIT_SUCCESS;
}

答案 1 :(得分:0)

你的i从0传递到2,并且你的索引永久地超出你的界限:你分配2个双打,并写入索引2,这是第三个。 别忘了关闭文件。 并且最终打印使用i应该使用n。混合常用字母(i代表循环索引,n代表极限)并不好,最后每个人都会感到困惑。

最好简化/分解代码,如下所示,以避免错误:

作为奖励,我添加了一种避免每次重新分配的机制,这在性能方面不是很好。

以下代码已经过测试并正常工作

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

int main()
{
FILE *ifile = fopen("numbers.txt", "r");
double v,*note=NULL;
int i = 0,n; 
int alloc_step = 10;
int note_size = 0;

while ( !feof( ifile)) {
      fscanf( ifile, "%lf", &v);
      if ((i % alloc_step)==0)
      {
          note_size += alloc_step;
          note = (double *) realloc( note, note_size * sizeof( double));
      }
      note[i++] = v;

}       

for (n=0; n < i; n++) {
     printf( "%lf\n", note[n]);
}
fclose(ifile);
}