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



说我有一个未指定大小为数字的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( "%lfn", note[i]);
}

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

在(错误的)while循环中,它总是比最后一个元素晚一个(例如,在第一次迭代中,i变为2,分配了足够两个double的空间,但您访问了第三个note[2])。

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

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

这些问题的快速解决方案可以是以下片段。请注意,我(每次)都使用了与您相同的重新分配策略,但正如@Serge Ballesta所指出的,这可能效率低下。例如,看看@Jean-François Fabre回答中显示的备选方案。

#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( "%lfn", note[i]);
    }
    free(note);     // <-- don't leak memory!
    fclose(ifile);
    return EXIT_SUCCESS;
}

您的i从0传递到2,并且您的索引永久超出您的边界:您分配2个doubles,并写入索引2,这是第三个。另外,不要忘记关闭您的文件。最后的印刷品在应该使用n的地方使用了i。把通常的字母(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( "%lfn", note[n]);
}
fclose(ifile);
}

相关内容

  • 没有找到相关文章

最新更新