|
|
|
|
公众号矩阵

12.19 用"%d\n"调用scanf从键盘读取为什么多输入一行才返回

《你必须知道的495个C语言问题》第12章标准输入输出库,本章的很多问题都跟printf(问题12.7到12.12)和scanf(问题12.13到12.22)有关。本小节为大家介绍我像这样用"%d\n"调用scanf从键盘读取数字。

作者:孙云/朱群英来源:人民邮电出版社|2009-01-16 10:01

scanf问题

尽管scanf看起来好像不过是和printf互补的函数,但它却有许多基本的限制,有的程序员建议干脆完全避免使用它。

12.19

问:我像这样用"%d\n"调用scanf从键盘读取数字:

int n; 
scanf("%d\n", &n);
printf("you typed %d\n", n);

好像要多输入一行才返回。为什么?

答:可能令人吃惊,\n在scanf格式串中不表示等待换行符,而是读取并放弃连续的空白字符。(事实上,scanf格式串中的任何空白字符都表示读取并放弃空白字符。而且,诸如%d这样的格式也会扔掉前边的空白,因此你通常根本不需要在scanf格式串中加入显式的空白。)

因此,"%d\n"中的\n会让scanf读到非空白字符为止,而它可能需要读到下一行才能找到这个非空白字符。这种情况下,去掉\n仅仅使用"%d"即可(但你的程序可能需要跳过那个没有读入的换行符。参见问题12.20。)

scanf函数是设计来读取自由格式的输入的,而在读取键盘输入的时候,你所得到的往往并不是你所想要的。"自由格式"意味着scanf在处理换行符的时候跟其他的空白一样。格式"%d%d%d"既可读入

1 2 3
又可以读入
1 
2
3

(比较一下就可得知,C、Pascal和LISP的源码是自由格式的,而BASIC和FORTRAN的则不是。)

如果你真的要坚持,scanf的确可以用"scanset"指令读取换行符:

scanf("%d%*[\n]", &n);

scanset尽管功能强大,但还是不能解决所有的scanf问题。参见问题12.22。

参考资料: [19, Sec. B1.3 pp. 245-246]
[35, Sec. 4.9.6.2]
[8, Sec. 7.9.6.2]
[11, Sec. 15.8 pp. 357-364]

【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

我的运维日志系统构建之路

我的运维日志系统构建之路

数据驱动运维
共18章 | 我叫于小炳

191人订阅学习

CentOS文件服务的最佳实战

CentOS文件服务的最佳实战

涨薪跳槽必备技能
共15章 | 追风蚂蚁

88人订阅学习

小白网工宝典

小白网工宝典

一次搞定思科华为
共15章 | 思科小牛

431人订阅学习

读 书 +更多

精通JBuilder 2006

JBuilder 2006是一款强大的Java企业级开发平台,其集成了几乎所有的Java技术,涵盖了软件开发生命周期的各个过程。本书深入浅出地介绍了JBu...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客