《你的月亮我的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”。

猜你喜欢

转载自blog.csdn.net/justinzengtm/article/details/81069202