C:多个scanf,当我输入一个scanf的值时,它会跳过第二个scanf

Sno*_*Mac 20 c scanf

我有这个代码块(函数省略,因为逻辑是家庭作业的一部分):

#include <stdio.h>

int main()
{
    char c = 'q';
    int size; 

    printf("\nShape (l/s/t):");
    scanf("%c",&c);

    printf("Length:"); 
    scanf("%d",&size);

    while(c!='q')
    {
        switch(c)
        {
            case 'l': line(size); break; 
            case 's': square(size); break;
            case 't': triangle(size); break; 
        }


        printf("\nShape (l/s/t):");
        scanf("%c",&c);

        printf("\nLength:"); 
        scanf("%d",&size);
    }

    return 0; 
}
Run Code Online (Sandbox Code Playgroud)

前两个Scanf的工作很好,没有问题,一旦我们进入while循环,我有一个问题,当你应该被提示输入一个新的形状char时,它会跳转到printfLength的长度并等待输入从那里获取一个char,然后是循环的下一次迭代的小数.

Preloop迭代:

Scanf:形状.Works Great
Scanf:长度.没问题

循环1.

Scanf:形状.跳过此
Scanf:长度.问题,这个scanf映射到形状char.

循环2
Scanf:形状.跳过此
Scanf:长度.问题,这个scanf现在映射到int大小.

它为什么这样做?

Tho*_*thy 38

scanf("%c")ENTER键中读取换行符.

当你输入时15,你输入a 1,a 5然后ENTER按键.所以输入缓冲区中现在有三个字符.scanf("%d")读取15解释它们作为数字15,但换行符仍然在输入缓冲区中.该scanf("%c")会立即阅读换行符,然后程序将进入到下一个scanf("%d"),并等待你输入一个数字.

通常的建议是读取整行输入fgets,并在单独的步骤中解释每行的内容.对您当前问题的一个更简单的解决方案是getchar()在每个之后添加一个scanf("%d").

  • `scanf("%d"); getchar();`如果用户在数字后意外输入空格(或其他垃圾),则组合失败. (2认同)

Jon*_*ler 19

基本问题是scanf()将新行留在缓冲区中的数字后面,然后%c在下一遍中读取它.实际上,这很好地证明了我不使用的原因scanf(); 我使用线路阅读器(fgets()例如)和sscanf().它更容易控制.

你可以通过使用" %c"而不是"%c"格式字符串来拯救它.空白导致scanf()在读取字符之前跳过空格(包括换行符).

但它会从长远来看更容易放弃scanf()fscanf()并使用fgets()或同等学历加sscanf().除此之外,当您使用整个字符串时,错误报告会更容易,而不是在scanf()失败后留下的小滴.

您还应始终检查是否获得了转换后的值scanf().输入失败 - 经常和可怕.因为你没有检查,所以不要让它破坏你的程序.


noM*_*MAD 6

使用该功能

void seek_to_next_line( void )
{
    int c;
    while( (c = fgetc( stdin )) != EOF && c != '\n' );
}
Run Code Online (Sandbox Code Playgroud)

清除输入缓冲区.


小智 5

尝试在scanf中添加空格.

scanf(" %d", &var);
//     ^
//   there
Run Code Online (Sandbox Code Playgroud)

这将导致scanf()在匹配整数之前丢弃所有空格.

  • 根据[第7.21.6.2p8节](http://port70.net/~nsz/c/c11/n1570.html#7.21.6.2p8),`scanf`会*通常*在匹配整数之前丢弃所有空格,无论如何,呈现此格式字符串中的空白毫无意义:*“输入空白字符(由 isspace 函数指定)将被跳过,除非规范包含 [、c 或 n 说明符。”* (2认同)
  • 这不会解决问题。`%d` 已经跳过前导空白字符。 (2认同)