编译器在double之后跳过scanf语句以获取包机输入。为什么会这样?

时间:2016-03-30 14:30:55

标签: c types scanf

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

int main()
{
    int intvar=0; //variable to store integer input
    double decimalvar = 0; //variable to store double input
    char string[30]; //arrary to store string

    scanf("%d",&intvar); //scan for int input
    scanf("%f",&decimalvar); //scan for double input
    scanf("%[^\n]",string); //scan for a line input

    printf("%d\n",intvar); //print int var
    printf("%.1f\n",decimalvar);//print double var
    printf("%s",string);//print string

    return 0;
}

程序运行成功,但只需要两个输入。输入第二个输入后,将跳过第三个scanf语句并执行printf语句。为什么会这样?

3 个答案:

答案 0 :(得分:1)

scanf("%f",&decimalvar); 

应该是:

scanf("%lf",&decimalvar); 

因为您传递的是double而不是float

这是技术上未定义的行为,但不是导致问题的原因,即scanf调用后在stdin缓冲区中保留换行符。 dflf等说明符会消耗并忽略该换行符。当然,说明符[^ \ n]找到换行符并在stdin缓冲区中留下一些输入时停止读取。

要解决此问题,请在尝试读取标准输入之前在scanf格式字符串的开头添加一个空格,该字符串将使用换行符。

scanf(" %[^\n]",string);

答案 1 :(得分:1)

执行每个scanf()语句后,&#39; \ n&#39;留在stdin。在执行scanf("%[^\n]", string);时,该&#39; \ n&#39;立即导致匹配失败("%[^\n]"期望除了&#39; \ n&#39;)以外的所有字符,因此scanf()遗憾地返回。

要解决此问题,只需在格式字符串中添加一个前导空格即可丢弃所有(0个或更多)空格字符,如下所示:

scanf(" %[^\n]", string);

一些不相关的提示:

  1. scanf("%f", &decimalvar);更改为scanf("%lf", &decimalvar);以避免未定义的行为。请参阅Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?
  2. 使用fgets(string, sizeof string, stdin)防止潜在的缓冲区溢出。

答案 2 :(得分:0)

scanf("%[^\n]",string);  

应该是

scanf("%s",string);