【问题标题】:The compiler skips the scanf statement for charter input after double. Why does this happen?编译器在 double 之后跳过用于charter 输入的 scanf 语句。为什么会这样?
【发布时间】:2016-07-18 15:21:21
【问题描述】:
#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语句。为什么会这样?

【问题讨论】:

  • 1) scanf("%[^\n]",string); --> scanf(" %[^\n]",string); (加空格) 2) 不要使用scanf() 使用fgets() 然后sscanf()

标签: c types scanf


【解决方案1】:
scanf("%[^\n]",string);  

应该是

scanf("%s",string);

【讨论】:

    【解决方案2】:

    在每个scanf() 语句执行后,stdin 中会留下一个“\n”。在执行scanf("%[^\n]", string); 时,'\n' 会立即导致匹配失败("%[^\n]" 需要除'\n' 之外的所有字符),所以scanf() 遗憾地返回。

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

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

    一些不相关的提示:

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

    【讨论】:

      【解决方案3】:
      scanf("%f",&decimalvar); 
      

      应该是:

      scanf("%lf",&decimalvar); 
      

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

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

      为了解决这个问题,在 scanf 格式字符串的开头添加一个空格,这将消耗换行符,然后再尝试读取标准输入。

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

      【讨论】:

      • @CoolGuy 谢谢,已添加。
      • "停止读取,同时在标准输入缓冲区中留下一些输入" - 一些输入?它失败并将\n留在stdin中。
      • @CoolGuy 是的,一些输入,无论输入什么。这包括换行符。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      • 2017-05-02
      • 2012-06-11
      • 2014-07-06
      • 2010-12-02
      • 2020-08-15
      • 1970-01-01
      相关资源
      最近更新 更多