今天在做K&R上面的练习,用scanf()函数写一个简单的后缀计算器,遇到了以下问题:
源程序如下(linux 下 用 gcc编译的):
#include <stdio.h> main() { int a, b, c, temp, temp2; a = b = c = 0; scanf("%d", &a); scanf("%d", &b); temp = scanf("%d", &b); temp2 = scanf("%c", &c); printf("a is : %d\n", a); printf("b is : %d\n", b); if (c == '\n') printf("c is a <LF>\n"); else printf("c is: %d(%c)\n", c, c); printf("temp is : %d\n", temp); printf("temp2 is : %d\n", temp2); }
当我的输入是:
“1 234 *“(星号('*')后面直接跟一个回车,1 和 234 还有 加号之间有个空格)时,
程序的输出为:
1 234 *
a is : 1
b is : 234
c is: 42(*)
temp is : 0
temp2 is : 1
由程序的输出结果,可以分析出,1 和 234 都分别成功赋值给了a和b,在第三次调用scanf()时(temp = scanf("%d", &b)),由于加号(‘*’)并非数字,所以匹配失败,scanf()返回0给temp,表示没有成功匹配和赋值,b还保持原来的值(234)。此时,匹配失败的星号('*')被重新放回缓存区中(其后当然还跟着一个换行符'\n'),所以在最后一次调用scanf()函数时,星号被重新由缓存区中读取出来,与"%c"格式控制符匹配并且匹配成功,于是赋值给了c。成功匹配完参数的scanf()函数返回匹配数 1 给temp2变量。整个main()函数宣告结束,虽然缓存区中还有个换行符没有被读取。
这个过程我都能理解,但是下面的我就很疑惑了:
当我的输入是:
“1 234 +”(加号后面直接跟一个回车,1 和 234 还有 加号之间有个空格)时,
输出为:
a is : 1
b is : 234
c is a <LF>
temp is : 0
temp2 is : 1
也即是说,1 和 234 都分别成功赋值给了a和b,在第三次调用scanf()时(temp = scanf("%d", &b)),由于加号(‘+’)并非数字,所以匹配失败,scanf()返回0给temp,表示没有成功匹配和赋值,b还保持原来的值,新读取但匹配失败的加号('+')应该放回缓存区中。在最后一次的scanf()的调用中,加号应该会被重新读取并赋值给c,却为何是其后的换行符('\n')被赋值了呢?
在这一点上我十分之不理解。而且经过测试,发现减号(‘-’)也有这个情况,就是当匹配失败时都好像被直接丢弃,而不是向遇到星号和其它符号一样被放回缓存区中等待下次的读取。
这是什么原因呢?请有相关经验的前辈出来说说,替我这个小菜解解惑。Thanks~
因为 + 和 - 是属于有效输入中的一部分,想一下你要输入正数(可以额外添加+号)或负数。所以它们不会被放回去。
######这个理解不错######相信这位兄弟没有看过 itoa, atoi 之类的库函数, 看过库函数你就知道了
so easy
######因为 + 和 - 是属于有效输入中的一部分,想一下你要输入正数(可以额外添加+号)或负数。所以它们不会被放回去。
恩,是这样的。
你理解的很具体,很深入,是学编程的好苗子,呵呵。
######哈哈,十分感谢前辈,目前的问题已经解决了。对scanf()的理解也加深了不少,果然遇到问题努力解决才是提升的好方法。再次感谢前辈~版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。