我有一段代码提出了一个有趣的问题(在我看来)。
/*power.c raises numbers to integer powers*/
#include <stdio.h>
double power(double n, int p);
int main(void)
{
double x, xpow; /*x is the orginal number and xpow is the result*/
int exp;/*exp is the exponent that x is being raised to */
printf("Enter a number and the positive integer power to which\n the first number will be raised.\n enter q to quit\n");
while(scanf("%lf %d", &x, &exp) ==2)
{
xpow = power(x, exp);
printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
printf("enter the next pair of numbers or q to quit.\n");
}
printf("Hope you enjoyed your power trip -- bye!\n");
return 0;
}
double power(double n, int p)
{
double pow = 1;
int i;
for(i = 1; i <= p; i++)
{
pow *= n;
}
return pow;
}
如果您注意到要输入的数字的顺序是浮点数,然后是十进制数(基数,然后是指数)。但是当我输入带有整数基数和浮点指数的输入时,它会产生一个奇怪的结果。
[mike@mike ~/code/powerCode]$ ./power
Enter a number and the positive integer power to which
the first number will be raised.
enter q to quit
1 2.3
1 to the power 2 is 1
enter the next pair of numbers or q to quit.
2 3.4
0.3 to the power 2 is 0.09
enter the next pair of numbers or q to quit.
似乎将浮点指数的第二个数字推回到下一个输入。我希望有人可以解释幕后发生的事情。我知道这是scanf()的工作,不检查它的数组边界,但如果有人能给我一些更深刻的理解,我真的很感激它。 谢谢Stack Overflow。 -M.I。
编辑。 只是想感谢大家的意见。任何其他答案都更受欢迎。 再次感谢,S.O。
答案 0 :(得分:7)
这是因为当您使用scanf读取“2.3”时,扫描停止,但不消耗“。”在“.3”。因此,当您对scanf进行下一次调用时,它首先读入“.3”。
详细说明,scanf调用不限于一行文本。 scanf()跳过空格,包括制表符,空格和换行符。
答案 1 :(得分:5)
其他人已回答您的具体问题,但我想提供一条建议。 从不使用scanf()
或fscanf()
。永远。严重。
[f]scanf()
操作期间的失败总是将文件指针留在不确定的位置。由于来自用户的大多数输入通常基于行(GUI中除外),因此在我看来,使用fgets()
和sscanf()
的选项总是更好。
它的优点是将输入指针留在已知点(下一行的开头)和,允许您以多种不同的方式操作刚读入的行,而不仅仅是由scanf()
家庭指定。
换句话说,如果sscanf()
失败,您仍然可以将该行用于其他目的(使用不同的格式字符串重新扫描,甚至只是输出错误),而不必通过stdio
}体操回到文件中的行的开头(文件很难,终端的标准输入不可能)。
答案 2 :(得分:2)
当读取第一个“2.3”scanf时,读到“。”意识到它不再是一个有效的整数并停止。所以“.3”留在缓冲区中,然后输入“2 3.4”,因此“.3 \ n2 3.4”在缓冲区中。当scanf解析它得到“.3”和“2”就像你的例子所示。
答案 3 :(得分:2)
在C语言中,scanf()对于来自人类用户的真实世界输入基本无用 - 它用于从数据文件中读取固定格式的文本。如果您使用的是C ++,那么您应该使用iostream输入,在任何一种情况下,您都应该根据特定的输入要求编写自己的解析例程。
答案 4 :(得分:0)
我会阅读这些行并使用sscanf来解析每一行。我同意其他人的意见,但有比sscanf更好的方法。