提前感谢您花时间阅读我的问题...
/* Binary search for use with Gen_window.comp */
#include <stdio.h>
int main()
{
char line[1000];
double sig, E;
FILE *fp, *fopen();
fp = fopen("sig_data", "r");
if (fp==NULL){
printf("Error opening file!");
}
else {
printf("Processing file...");
}
while( (fgets(line, 25, fp) != NULL) ){
fscanf(fp, "%lf\t%lf", &E, &sig);
printf("\nThe energy is: %lf eV\nThe corresponding cross section is: %lf barns\n",E, sig);
}
}
文件中的数字格式为X.XXXXXX + X或X.XXXXXX-X。 C有办法将其指定为输入吗?没有'e'是不是很麻烦。我找不到任何有关输入指数的文档,只返回指数...
我不需要它来打印那种确切的格式,任何其他指数格式都可以。
我意识到我的%lf应该有一些说明符和精度,或者它应该是%e,但我已经尝试了对我有用的一切,所以我基本上把它留空了。
感谢您的帮助。
答案 0 :(得分:2)
不幸的是,C确实需要“e”。所以你必须自己解析输入。如:
#include <stdio.h>
#include <math.h>
double parse(const char** cursor)
{
int len;
double mantissa, exponent;
char sign;
sscanf(*cursor, " %lf%[+-]%lf%n", &mantissa, &sign, &exponent, &len);
*cursor += len;
return mantissa * pow(10, (sign == '-' ? -exponent : exponent));
}
int main()
{
char line[1000];
double sig, E;
FILE *fp, *fopen();
fp = fopen("sig_data", "r");
if (fp==NULL){
puts("Error opening file!");
return 1;
}
puts("Processing file...");
while( (fgets(line, 25, fp) != NULL) ){
const char* cursor = line;
E = parse(&cursor);
sig = parse(&cursor);
printf("The energy is: %e eV\nThe corresponding cross section is: %e barns\n",E, sig);
}
return 0;
}
(根据需要添加错误处理)
答案 1 :(得分:2)
Jester和plinth的答案大致正确,但有缺陷。确实无法使库存号解析例程(*scanf
,atof
,strtod
)以您拥有的格式处理数字。但是,建议的解决方法很糟糕。首先,我个人认为永远不应该使用*scanf
和ato*
,因为他们对畸形输入的处理非常糟糕。更严重的是,十进制到浮点转换需要扩展精度算法以避免精度损失。可以依赖strtod
(应该用于此问题的例程)来正确地执行此操作,但是分别处理尾数和指数然后以明显的方式组合它们不的。您需要一个大于double
的中间类型,并且您需要10的幂才能准确计算到最后一位,pow
无法可靠地给您。
所以我的建议是动态重写每一行,使strtod
可以接受。
\t
分割。我会手动执行此操作,但只要您使用fscanf
格式,就可以 使用%s
。确保每个缓冲区至少有两个额外的可用空间字节。+
或-
。使用memmove
将字符串的所有后续字节向下移动一个。将e
戳到符号原始位置的缓冲区中。 (如果您手动执行步骤1,则可以将此步骤与该步骤的循环结合使用。)strtod
可以处理的格式的数字。答案 2 :(得分:0)
char *splitAt(char *s, char *stops)
{
if (!s) return 0;
char *t;
for (t = s; *t && strchr(stops, *t) == NULL; t++)
;
int len = t - s;
t = malloc(len + 1);
strncpy(t, s, len);
t[len] = '\0';
return t;
}
double parse_my_float(char *input)
{
/* allocates a new string */
char *mantissaStr = splitAt(input, "+-"); /* check for null! */
double mantissa = atof(mantissaStr);
int len = strlen(mantissaStr);
free(mantissaStr);
int exponent = atoi(input + len);
return mantissa * pow(10, exponent);
}
答案 3 :(得分:0)
如何使用strtok和strtod,它应该很适合你。使用sscanf或fscanf非常容易出错。见下文:
const char* insertE(char* out, const char* src)
{
char* p = out;
while (*src) {
if (*src == '+' || *src == '-') {
*p++ = 'e';
}
*p++ = *src++;
}
return out;
}
.
.
.
char line[1000];
char tmp[100];
double sig, E;
FILE *fp;
char* end;
fp = fopen("sig_data", "r");
if (fp==NULL){
printf("Error opening file!");
return;
}
else {
printf("Processing file...");
while(! feof(fp) && (fgets(line, 1000, fp) != NULL) ) {
E = strtod(insertE(tmp, strtok(line, "\t")), &end);
sig = strtod(insertE(tmp, strtok(NULL, "\t")), &end);
printf("\nThe energy is: %lf eV\nThe corresponding cross section is: %lf barns\n", E, sig);
}
fclose(fp);
}
此附带通知,此代码假定输入文件格式正确。