《你的月亮我的C》(三):scanf 的那些事
1、用scanf("%d\n", &i);来输入数字,要多输入一行才返回,为什么?
输入4之后,要多输入一个换行和1,才能输出4。
这是因为,在scanf语句中“\n”不是表示换行符,而是表示读取并放弃连续的空白字符。scanf语句中任何的空白字符都表示读并放弃空白字符。例如在%d前的空白也会被放弃掉,所以在scanf格式串中不需要手动输入显式的空白字符。
所以,在scanf("%d\n", &i);的输入中,输入数字4后,直到找到下一个非空白字符为止,否则会一直读取并放弃空白的字符,所以你需要再输入一个非空白字符给它,它才会读取结束然后给你输出。
当然你也可以把%d后的\n去掉,这样在输入一个数字后回车立刻可以输出。
2、我们都知道使scanf(“%d”, &i),可是为什么i前面要带上“&”?
scanf的格式串里,传进去的参数其实是一个指针,所以scanf会把输入的值写入,传入指针指向的位置。
但这里有个特殊的地方是
这样是可以的。
想scanf传入一个数组时,数组总是以指针的方式传入函数,所以无论在scanf里,无论arr前加不加“&”,都是可以的。
3、scanf用%f不能输出double类型的值?
这样为什么不行?
在printf里,%f可以输出float和double类型的值。但scanf不同,scanf用%lf表示double类型,用%f表示float型。
即使如上图编译器没有报错且能运行,但d作为double类型接收不了float类型传入的值。
4、scanf输入流的问题。
先用scanf输入一个数字,然后用gets读取一个字符串,按照这样输入:
4
just
可是输出结果却是:
gets()被跳过去了,为什么?
scanf能读到输入的数字4,但之后输入的换行符被保留在了输入流中,然后被gets()读进去了,对于gets()来说相当于读进去了一个空行,“just”字符串并没有被读进去。
但如果你输入:4 just
则可以读入“just”字符串到gets()中。
5、当scanf遇到非合法字符。
看下这样一个程序:
看起来没问题。
可是如果我这样输入:
结果会怎样?
无限循环啦!
在scanf中,用%d举例,如果输入的值不是数字字符,都会被终止读入并保留在输入流中,scanf不会越过错误的非数字字符来处理后面的合法数字字符,所以在输入流中永远都会存在那个非数字字符,从而导致无限循环的出现。
至于证明scanf真的把非合法字符保留在了输入流中,你可以这样写个代码来证明:
假设%d中没有把非合法字符”a”保存在了输入流中,那么%s读入的应该是”bc”而不是”abc”。