所以我认为这应该是非常直截了当的。我实际上甚至无法理解可能出现的问题,这就是最让我烦恼的事情。
这是交易:我必须从文件中读取几个数字,但这些数字是科学记数法。示例文件的数字如下:
1.00090E+00,2.90000E+00
所以我想我只是这样读它:得到一个double,忽略一个字符,得到一个int,忽略一个字符,得到另一个double,忽略一个字符,并得到一个最终的int,所以对于这个例子,它会:
get (1.00090)
ignore (E)
get (+00)
ignore (,)
get (2.90000)
ignore (E)
get (+00)
所以,我写了这些fscanf:
fscanf(arquivo, " %lf%*c%d%*c", &mantissa1, &expoente1);
x[i] = numToFloat(mantissa1, expoente1);
fscanf(arquivo, "%lf%*c%d", &mantissa2, &expoente2);
fx[i] = numToFloat(mantissa2, expoente2);
我将它们分开以使理解更简单。但是,它不起作用。它正确地读取了第一个双精度,然后它弄乱了int。然后它弄乱了第二个fscanf上的所有东西。
我尝试了所有我能想到的。将格式化的字符串放在fscanf("%lfE%d,"
和"%lfE%d"
)上。将信号读入字符变量("%lf%*c%c%d%*c"
)。它都不起作用。
有什么猜错?
答案 0 :(得分:1)
首先,您不需要分别解析尾数和指数。 scanf
原生地理解n.nnnE±nnn
符号。这就是为什么你的格式字符串不像你期望的那样; %lf
指令使用包含E+00
部分的整个第一个数字,然后%*c
使用逗号,%d
2
,现在我们绝望了同步。
第二,you should not use any of thescanf
functions, ever。相反,一次使用fgets
(或getline
,如果有的话)阅读一行,请使用strtok
将其拆分为逗号,并使用strtod
将数字转换为二进制(它本身也理解科学记数法)。这将是更多的编码,但结果将更容易阅读和调试,它将更容易使其对格式错误的输入具有健壮性,并且它将在输入溢出时具有良好定义的行为。
(从技术上讲,您不需要使用strtok
,因为strtod
会告诉您每个号码的结束位置,但概念上更容易先进行拆分。)
答案 1 :(得分:0)
您可以根据需要调整此示例,它使用%lg
格式说明符:
#include <stdio.h>
int main(void){
double d, e;
int n;
printf("Enter 2 scientific floats: ");
fflush(stdout);
n = scanf("%lg %*c %lg", &d, &e);
if(n == 2) {
printf("%f\n", d);
printf("%f\n", e);
} else {
printf("Bad input\n");
}
}
计划会议
Enter 2 scientific floats: 1.8e+4,4.2e-1
18000.000000
0.420000