鱼C论坛

 找回密码
 立即注册
查看: 2327|回复: 20

[已解决]一个关于scanf的问题

[复制链接]
发表于 2018-8-27 13:14:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
捕获.PNG
捕获2.PNG
这个scanf加了一个换行就要输入2次,想问一下是什么原理,而且他读取的为啥是前面那个,感觉看网上应该是读取后面那个才对,求大神解释一下
最佳答案
2018-8-27 23:12:24
我是萌新啦,对前辈的问题很感兴趣,特地在网上查了资料
看到一个博客。
以下是我的想法:

用scanf函数输入的字符串是先存放在键盘缓冲区的。

读取时,按照缓冲区的先后顺序,依据scanfb函数中的字符串的格式进行读取的,因此它读取的就是排在前面的11,而不是后而的128

至于要输入两次的原因是:

一般情况下,回车符是作为确认输入用的,但你的scanf的格式中有了'\n',所以在你输入的回车符,计算机只是认为你的输入符合的格式,已经被计算机接收,正在等待你的确认。

但在这之后输入回车符没有反应,是因为你先前输入的字符已经被计算机接收,不在键盘缓冲区之中,之后的回车符被认为是先导空白字符(空白符:指空格符、制表符、回车符),而scanf函数的特性之一,就是忽略所有的先导空白字符,除非你的第一个字符就是'%c’。

因此,你必须再输入一个非先导空白字符,之后再输入的回车才被认为是确认输入。

解决办法:

scanf函数改为:scanf("%d",i);

即不要回车。

参考博客:https://blog.csdn.net/weiweicsdn1/article/details/52185453
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-27 13:27:00 | 显示全部楼层
是的, scanf(“%d”, &i); // 要求输入是数字
scanf(“%d\n”, &i); // 要求输入是数字与回车
scanf(“%d,”, &i); // 要求输入是数字与逗号
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2018-8-27 18:03:42 | 显示全部楼层
原理对吧,买一本书《C primer plus》
输入分无缓存输入和缓冲输入。
scanf属于缓冲输入。你在键盘按下一个字符,字符转为ASCII存储在一段内存空间。给这个一段内存起一个名字就是输入缓存区。然后依靠scanf第一个参数的字符串进行计算。提取对应的字符串内存
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-27 18:03:56 | 显示全部楼层
claws0n 发表于 2018-8-27 13:27
是的, scanf(“%d”, &i); // 要求输入是数字
scanf(“%d\n”, &i); // 要求输入是数字与回车
scanf( ...

那个敲数字与回车为啥打印的是前面那个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-27 18:23:59 | 显示全部楼层
孤世星辰 发表于 2018-8-27 18:03
那个敲数字与回车为啥打印的是前面那个

\n 是回车的意思,就如你在 printf("...\n", ..) 会空行。不信的话,多加一行 printf("...")。如果去掉 \n 会是只有一行

%d 对应整型
%f 对应浮点型
%c 对应字符
%s 对应字符串

目前先了解这些
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-27 19:44:07 | 显示全部楼层
关键是感觉 发表于 2018-8-27 18:03
原理对吧,买一本书《C primer plus》
输入分无缓存输入和缓冲输入。
scanf属于缓冲输入。你在键盘按下一 ...

没怎么看懂,cpp我买了,就是能讲一下实际的例子么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-27 23:01:39 | 显示全部楼层
claws0n 发表于 2018-8-27 18:23
\n 是回车的意思,就如你在 printf("...\n", ..) 会空行。不信的话,多加一行 printf("...")。如果去掉 \ ...

对应字符是知道的,就是想问一下为什么输入2个用的是前面那个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-27 23:05:50 | 显示全部楼层
孤世星辰 发表于 2018-8-27 23:01
对应字符是知道的,就是想问一下为什么输入2个用的是前面那个

?scanf() 不需要 \n,打错了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-27 23:12:24 | 显示全部楼层    本楼为最佳答案   
我是萌新啦,对前辈的问题很感兴趣,特地在网上查了资料
看到一个博客。
以下是我的想法:

用scanf函数输入的字符串是先存放在键盘缓冲区的。

读取时,按照缓冲区的先后顺序,依据scanfb函数中的字符串的格式进行读取的,因此它读取的就是排在前面的11,而不是后而的128

至于要输入两次的原因是:

一般情况下,回车符是作为确认输入用的,但你的scanf的格式中有了'\n',所以在你输入的回车符,计算机只是认为你的输入符合的格式,已经被计算机接收,正在等待你的确认。

但在这之后输入回车符没有反应,是因为你先前输入的字符已经被计算机接收,不在键盘缓冲区之中,之后的回车符被认为是先导空白字符(空白符:指空格符、制表符、回车符),而scanf函数的特性之一,就是忽略所有的先导空白字符,除非你的第一个字符就是'%c’。

因此,你必须再输入一个非先导空白字符,之后再输入的回车才被认为是确认输入。

解决办法:

scanf函数改为:scanf("%d",i);

即不要回车。

参考博客:https://blog.csdn.net/weiweicsdn1/article/details/52185453
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-27 23:27:08 | 显示全部楼层
本帖最后由 claws0n 于 2018-8-27 23:28 编辑
孤世星辰 发表于 2018-8-27 23:01
对应字符是知道的,就是想问一下为什么输入2个用的是前面那个


?没反应?楼主是想问多重输入吗?

int a, b, c;
scanf("%d%d%d", &a, &b, &c);  // 输入时可以空格
scanf("%d %d %d", &a, &b, &c);  // 输入时可以空格
scanf("%d,%d,%d", &a, &b, &c);  // 输入时需要逗号,并且不可以空格
scanf("%d, %d, %d", &a, &b, &c);  // 输入时需要逗号,但可以空格
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 09:15:04 | 显示全部楼层
claws0n 发表于 2018-8-27 23:05
?scanf() 不需要 \n,打错了吧

我知道不需要\n就是想问打了为啥会这样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 09:21:30 | 显示全部楼层
孤世星辰 发表于 2018-8-28 09:15
我知道不需要\n就是想问打了为啥会这样

打了,scanf就会expect(翻译成期待吧)一个'\n',所以只有碰到这个字符才会结束

点评

然后结束scanf的输入也需要'\n',总共需要2尺  发表于 2018-8-28 09:21
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 09:42:20 | 显示全部楼层
星球杯 发表于 2018-8-27 23:12
我是萌新啦,对前辈的问题很感兴趣,特地在网上查了资料
看到一个博客。
以下是我的想法:

嗯嗯,懂了,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 09:44:50 | 显示全部楼层
claws0n 发表于 2018-8-27 23:27
?没反应?楼主是想问多重输入吗?

int a, b, c;

额不说多重输入是scanf后面有一个换行要输入2此数据的问题,已经解决了谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 09:50:32 | 显示全部楼层
无符号整形 发表于 2018-8-28 09:21
打了,scanf就会expect(翻译成期待吧)一个'\n',所以只有碰到这个字符才会结束

那么期待下一个回车为什么还要在输入一次数据,不可以直接\n呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 09:53:22 | 显示全部楼层
孤世星辰 发表于 2018-8-28 09:50
那么期待下一个回车为什么还要在输入一次数据,不可以直接\n呢

因为期待下一个回车啊 你可以输入数据按两次\n啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 09:57:53 | 显示全部楼层
无符号整形 发表于 2018-8-28 09:53
因为期待下一个回车啊 你可以输入数据按两次\n啊

输入一个数据连续按2次回车也没用啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 11:45:04 | 显示全部楼层
孤世星辰 发表于 2018-8-28 09:57
输入一个数据连续按2次回车也没用啊

其实在 2 楼的时候就回答你了。引号里边有什么,scanf() 就会期待用户输入什么,再以回车确保输入完成,但是缓存区还会保留最后一次的回车
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 15:27:38 | 显示全部楼层
孤世星辰 发表于 2018-8-27 19:44
没怎么看懂,cpp我买了,就是能讲一下实际的例子么

里面有一段专门讲解这个,大概原理就是我上面描述的那样。缓冲输入,你按下什么键就会在缓存区储存,
你按下:aaaaa 缓存区储存:65 65 65 65 65 65 00  然后利用scanf第一个参数的字符串去缓存区分离字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 16:27:17 | 显示全部楼层
关键是感觉 发表于 2018-8-28 15:27
里面有一段专门讲解这个,大概原理就是我上面描述的那样。缓冲输入,你按下什么键就会在缓存区储存,
你 ...

哦哦谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 06:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表