为什么scanf似乎跳过输入?

Eig*_*ght 5 c c++ io cout scanf

我对以下程序中scanf的行为感到困惑.scanf似乎输入一次,然后不再输入,直到打印出一串字符.

下面是C程序

#include<stdio.h>
int main()
{
    int i, j=0;

    do
    {
        ++j;
        scanf("%d", &i);
        printf("\n\n%d %d\n\n", i, j);
    }
    while((i!=8) && (j<10));  

    printf("\nJ = %d\n", j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这里,直到我输入任何整数程序工作得很好,但是当输入一个字符时,它继续打印i的最后一个输入值并且永远不会停止(直到循环退出时j为10),以便scanf接受下一个输入.

output::  
1    <-----1st input
1 1
2    <---- 2nd input
2 2
a    <---- character input
2 3  
2 4
2 5
2 6
2 7
2 8
2 9
2 10

J = 10  
Run Code Online (Sandbox Code Playgroud)

同样的事情也在c ++中发生.

#include<iostream>
using namespace std;
int main()
{
    int i, j=0;

    do
    {
        ++j;
        cin>>i;
        cout<<i<<" "<<j<<"\n";
    }
    while((i!=8) && (j<10));

    cout<<"\nj = "<<j<<"\n";
}   


output of c++ program ::  
1     <-----1st input
1 1
2     <-----2nd input
2 2
a    <------ character input
0 3
0 4
0 5
0 6
0 7
0 8
0 9
0 10

j = 10  
Run Code Online (Sandbox Code Playgroud)

只有c ++的变化才是打印0而不是最后一个值.

我知道程序需要整数值,但我想知道输入字符代替整数时会发生什么?上面发生的一切是什么原因?

Naw*_*waz 6

当你进入a,则cin >> i无法读取,因为它的类型iint哪个角色不能被读取.这意味着,a永远留在流中.

现在为什么i印刷品0是另一回事.实际上它可以打印任何东西.i一旦尝试读取失败,则不定义内容.类似的事情也发生了scanf.

写这个的正确方法:

do
{
    ++j;
    if (!(cin>>i)) 
    {
       //handle error, maybe you want to break the loop here?
    }
    cout<<i<<" "<<j<<"\n";
}
while((i!=8) && (j<10));
Run Code Online (Sandbox Code Playgroud)

或者只是这个(如果你想在出现错误时退出循环):

int i = 0, j = 0;
while((i!=8) && (j<10) && ( cin >> i) )
{
    ++j;
    cout<<i<<" "<<j<<"\n";
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ode 5

如果scanf在输入流中看到与转换说明符不匹配的字符,它将停止转换并在输入流中保留有问题的字符.

有几种方法可以解决这个问题.一个是阅读一切为文本(使用scanf一个%s%[转换符或fgets),然后使用atoistrtol进行转换(我的首选方法).

或者,您可以检查返回值scanf; 它将指示成功转换的次数.所以,如果scanf("%d", &i);等于0,那么你知道输入流中有一个坏字符.你可以使用它,getchar()然后再试一次.