0

我有多个文本文件,其数据如下:

    0.000000E+0 0.000000E+0
    1.800000E-1 0.000000E+0
    4.200000E-1 0.000000E+0
    6.950000E-1 0.000000E+0
    9.450000E-1 0.000000E+0
    1.225000E+0 0.000000E+0

这是由测试仪器生成的。两列数据由制表符分隔。我正在尝试将此数据文件读入程序以进行进一步处理。我写的代码如下:

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

float **make_array(int size); //function to make 2D array

int main(int argc, char **argv)
{
        FILE *infile;
        infile=fopen(argv[1], "r");

//count number of lines in file
        char c;
        int i=0, numlines=0;
        while((c=fgetc(infile))!=EOF)
                if(c == '\n') numlines++;

        printf("numlines: %d\n", numlines);

        float **entry = make_array(numlines);

//read inputfile
        for(i=0; i< numlines; i++)
                fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]);
//verify read values
        printf("\n");
        for(i=0; i<numlines; i++)
                printf("%E\t%E\n", entry[0][i], entry[1][i]);

//clean up before exiting
        free(entry[0]);
        free(entry[1]);
        free(entry);
        fclose(infile);
return 0;
}


//create a 2D array of 2 by {size}
float **make_array(int size){
        int i;
        float **entry = malloc(2*sizeof(float *));
        if(entry==NULL) exit(1);
        entry[0] = malloc(size*sizeof(float *));
        for(i=0;i<size;i++) entry[0][i] == 0.0;
        entry[1] = malloc(size*sizeof(float *));
        for(i=0;i<size;i++) entry[1][i] == 0.0;

return entry;
}

当我编译并运行程序时,它会正确打印出文件中的行数,但用于验证读入数组的数据的 printf 语句entry只会打印出全零,如下所示:

numlines: 252

0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00
0.000000E+00    0.000000E+00

我尝试了不同的格式说明符,fscanf%g,%e,%f,%G etc它们都给出了相同的结果。另外,我正在使用带有 GCC 4.6 的 Ubuntu 12.04。任何指向错误的指针将不胜感激。

卡迪亚。

4

3 回答 3

4

您的初始循环:

while((c=fgetc(infile))!=EOF)
    if(c == '\n') numlines++;

读取整个输入文件(以确定数组的大小)。一旦你这样做了,你对fscanfall 的调用就会失败,因为你已经在文件的末尾了。

假设输入文件是可查找的(如果它是磁盘文件则应该是可查找的),您可以使用rewind()fseek()回到开头并再次读取它。

顺便说一句,您使用%G%E格式说明符是有效的,但%g%e常见(并且应该以完全相同的方式工作)。

你真的应该argc在引用之前检查argv[1]; 如果在没有命令行参数的情况下调用该程序可能会崩溃。您还应该检查是否fopen()成功,fscanf()返回 2 表示它成功读取了两个数据项。

于 2012-06-28T20:44:21.120 回答
1

所以,问题出在:

while((c=fgetc(infile))!=EOF)
            if(c == '\n') numlines++;

执行该 while 循环后,您的 FILE* 指向 EOF,因此当您到达:

for(i=0; i< numlines; i++)
            fscanf(infile, " %G\t%G", &entry[0][i], &entry[1][i]);

每个 fscanf 返回 EOF 并且您根本不扫描值。

于 2012-06-28T20:54:23.643 回答
0

基思指出了问题,但您应该考虑其他一些事情:

  • 检查结果fscanf;它将返回成功转换和分配的数量。如果返回小于 2,则说明您没有正确读取数据;

  • 您在malloc调用中使用了错误的数据类型entry[0]and entry[1]; 你应该使用sizeof (float),而不是sizeof (float *)。你可以通过写来清理entry[0] = malloc(sizeof *entry[0] * size);——这样你就不会出现那种类型的不匹配。

  • 两次读取文件效率低下且不必要;由于无论如何您都在动态分配数组,因此您可以在读取文件 时扩展entry[0]entry[1]使用数组的大小。realloc

于 2012-06-28T20:55:32.223 回答