[英]Problems reading numbers in scientific format in C using fscanf()
我有多个文本文件,其数据如下:
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;
}
当我编译并运行程序时,它会正确打印出文件中的行数,但是用于验证读取到数组entry
的数据的printf语句只会打印出全零,如下所示:
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。 任何指出问题的指针将不胜感激。
哈蒂嘉。
您的初始循环:
while((c=fgetc(infile))!=EOF)
if(c == '\n') numlines++;
读取整个输入文件(以确定数组的大小)。 完成此操作后,对fscanf
的调用都会全部失败,因为您已经在文件末尾了。
假设输入文件是可搜索的(如果它是磁盘文件,则应该是该文件),您可以使用rewind()
或fseek()
返回到开头并再次读取它。
顺便说一句,您使用%G
和%E
格式说明符是有效的,但%g
和%e
更常见(并且应以完全相同的方式工作)。
在引用argv[1]
之前,您确实应该检查argc
的值; 如果不使用命令行参数调用该程序,则可能会崩溃。 您还应该检查fopen()
是否成功,并且fscanf()
返回2表示它成功读取了两个数据项。
因此,问题出在:
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,您根本不会扫描这些值。
基思指出的问题,而是一些其他的事情你应该想想:
检查fscanf
的结果; 它将返回成功的转换和分配的数量。 如果返回的值小于2,则说明您无法正确读取数据;
您在malloc
调用entry[0]
和entry[1]
使用了错误的数据类型; 您应该使用sizeof (float)
,而不是sizeof (float *)
。 您可以通过编写entry[0] = malloc(sizeof *entry[0] * size);
来清理内容entry[0] = malloc(sizeof *entry[0] * size);
-这样一来,您就不会遇到类型不匹配的情况。
两次读取文件效率低下且不必要。 由于您还是要动态分配数组,因此可以在读取文件时使用realloc
扩展entry[0]
和entry[1]
的大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.