[C/C++] 详解getline与getchar的一个著名的坑

1.scanf()所做工作的本质

读取 从第一个非空白符起,到第一个空白符之前的内容。

简记为[非空开始,空前结束]

不妨试试以下例子:

char a[10], b[10], c[10];
scanf("%s", a);
printf("a=%s\n", a); 
scanf("%s", b);
printf("b=%s\n", b);
scanf("%s", c);
printf("c=%s\n", c);

键盘输入内容:

其中输入内容里的\n代表按下了回车的意思,并非真的依次按下\和n两个键。

样例一:

  aa  bbb\n c\n

橙色就是留在输入缓冲区中的内容,它们还没有被读取到某个变量中。

输出结果:

a=aa
b=bbb
c=c

分析:第一个scanf读取的内容:

输入缓冲区开头前两个空格符被丢弃,用灰色呈现。

两个非空字符'a'被读取到字符数组a中,被读取内容用绿色呈现。

仍留在输入缓冲区中的内容,用橙色呈现。

第二个scanf读取的内容:

橙色缓冲区开头的前两个空格还是被丢弃,三个非空字符'b'被读取到字符数组b中,注意后面的换行符\n仍然留在缓冲区中。

第三个scanf读取的内容:

 橙色缓冲区开头的一个'\n'和一个空格都被丢弃,而非空字符'c'被读取到字符数组c中,注意最后的换行符\n仍然留在缓冲区中。

 

 


2.getline()所做工作的本质

读取 从缓冲区第一个字符开始,到第一个换行符之前的内容,并且缓冲区会丢弃读取内容之后的一个换行符。

简记为[缓冲开始,回车前结束]

以下例子:

string a, b, c;
getline(cin, a);
cout << "a=" << a << endl;
getline(cin, b);
cout << "b=" << b << endl;
getline(cin, c);
cout << "c=" << c << endl;

键盘输入内容:

其中输入内容里的\n代表按下了回车的意思,并非真的依次按下\和n两个键。

样例一:

  aa  bbb\n c\n

橙色就是留在输入缓冲区中的内容,它们还没有被读取到某个变量中。

输出结果:

a=  aa  bbb
b= c
(此处光标正在等待输入)

那么,发生了什么事情呢?

第一个getline:

缓冲区开头(包括空格字符)直到bbb处的内容都被读取到字符串a中,并且b后面的\n被丢弃。

第二个getline:

 缓冲区开头(包括空格字符)直到c处的内容都被读取到字符串b中,并且c后面的\n被丢弃。

第三个getline:

由于上图已经没有橙色部分,也就是说,缓冲区空了,所以程序执行到第三个getline处时,你会看到一个光标在闪动,等待新的输入。

 

 

以下例子:

char a[10], b[10];
string c;
scanf("%s", a);
printf("a=%s\n", a); 
scanf("%s", b);
printf("a=%s\n", b); 
getline(cin, c);
cout << "c=" << c << endl;

输入样例一:

  aa  bbb\n c\n

橙色就是留在输入缓冲区中的内容,它们还没有被读取到某个变量中。

输出结果:

a=aa
b=bbb
c=

第三个getline很不幸吃到了一个回车。

(未完待续)

gets

cin

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值