3.2.2 数据的输入
特别强调一下,数据输入不常用,简单掌握即可,因为书写真正项目代码时一般不会从键盘上输入数据,更何况一旦输入错误还可能会导致程序执行出现异常。但作为学习的一部分,还是有必要掌握一下这部分内容,以方便以此为基础学习更多、更深入的新知识。
1.getchar函数
用于等待用户从键盘上输入一个字符,按Enter键后程序才会继续执行。该函数的格式为:
该函数不常用,作用也比较小,但却也有一个特殊用途:如果编写一个程序,执行起来后,发现出现的黑色执行结果窗口一闪而过消失不见(某些Visual Studio版本有这个问题),可以把这个函数调用放在main入口函数的最后一行,这样程序执行后将卡在黑窗口上等待用户输入一个字符并按Enter键后才能继续运行,如此一来,这个黑窗口就不会一闪而过消失不见,使用户能够看清程序输出的结果。看如下代码:
再看如下代码:
这有一个特别容易忽略的问题,也许不同版本的Visual Studio表现不同,在这里描述的是Visual Studio 2019中的问题,如果希望用户从键盘上输入一个字符,期望屏幕上输出用户刚才所输入的字符,然后希望用户再次从键盘上输入一个字符,继续期望屏幕上再次输出所输入的字符。为了实现这个想法,可能会用到两次getchar函数,看如下代码:
执行后,意外的事情发生了,屏幕上只允许用户输入一次字符,在输出了用户所输入的字符之后,整个程序的执行就结束了,为什么没让用户第二次输入字符呢?原因如下:
(1)当第一次执行“getchar();”让用户输入字符时,用户输入了一个字符,然后又输入了一个回车符,这等于用户一次输入了两个字符,问题的根源就在这里。
(2)于是,第一个“getchar();”得到了用户输入的第一个字符并利用putchar(c)输出到屏幕上,此时,执行到了第二个“getchar();”语句。
(3)开发者的本意是希望用户通过第二个“getchar();”从键盘上输入新字符,但实际上第二个getchar()会自动得到用户第一次执行“getchar();”时从键盘上输入的第二个字符也就是回车符,然后程序执行流程继续往下走了(而不是给用户机会等待用户从键盘上输入新字符)。
(4)所以第二个“putchar(c);”实际上是输出了一个用户看不见的回车符,然后结束整个程序的执行。
为了避免上述情形发生,最好在整个程序中只使用一次“getchar();”,看得出来,这并不是一个很好用的函数。
2.scanf函数
这是一个格式化输入函数,用于从键盘输入任何类型的一到多个数据。该函数的格式为:
该函数的格式和printf函数非常类似。特别值得一提的是,当用户从键盘上输入数据时,最后都需要输入回车符以表示整个输入数据的结束。看如下代码:
需要特别注意的是,尝试编译并执行程序的时候,因为Visual Studio版本的原因,有可能得到错误提示:error C4996:'scanf':This functionor variable maybe unsafe.Consider usingscanf_sinstead...,这个错误的大概意思是系统认为scanf函数不安全,建议用scanf_s取而代之。不需要理会这个建议,但需要改正错误,否则程序没办法编译执行,只需要在源代码文件的最上面位置,在#include命令行的下面,增加一行语句,该行语句的目的是让编译器忽略一些警告信息,从而可以正常使用scanf等函数,所增加的语句行内容如下:
言归正传,继续说前面的scanf函数范例,该范例的含义是让用户从键盘输入三个数据,并分别保存到a、b、c变量中,%d格式字符在前面讲printf函数时说过,在这里含义是按照十进制整型数据输入。输入这三个数据的时候要特别特别注意,三个待输入的数据之间可以用空格、回车、tab键分隔,但不可用逗号分隔,否则会得到错误的程序执行结果。
当然,如果把上述的scanf代码行改成如下这种写法,也就是在scanf函数的格式控制字符串中加入了逗号,看如下代码:
那么在输入数据的时候,也要在对应的所输入的数据之间输入逗号作为分隔,否则同样会得到错误的程序执行结果。输入的数据如图3.6所示。
同理,如果将scanf语句修改为如下内容:
这次,在scanf函数的格式控制字符串中加入了冒号,那么同样,在输入数据的时候,也要在对应的所输入的数据之间输入冒号作为分隔,才能保证得到正确的程序执行结果。输入的数据如图3.7所示。
图3.6 输入数据时用逗号分隔
图3.7 输入数据时用冒号分隔
当然,scanf函数不仅支持%d格式字符,还支持其他的多种格式字符,但其他的格式字符都不常用,在这里就不一一列举。如果希望进一步了解其他的格式字符,可以在搜索引擎中输入“scanf格式字符”,这将得到大量相关信息。
最后,针对scanf函数,再强调几点:
(1)scanf函数圆括号中的第二个参数开始,用的是变量地址,千万不要丢掉&符号,否则程序要么编译出错无法执行,要么执行后会报错崩溃。
(2)scanf是一个非常容易用错的函数,尤其是输入多个数据时,很容易因为输入的格式问题导致对应的变量并没有得到期望的结果,读者往往会发现程序最终执行不正确却不知道问题出在哪里,所以,建议在scanf语句之后,立即增加printf输出语句,通过输出查看通过scanf函数输入的变量值是否和预期的完全一样。例如,如下代码中第一个printf语句就是用于验证通过scanf输入的变量值是否是所期望的:
(3)当输入回车符后,整个scanf语句输入结束,此时如果还没输入完数据,则程序肯定不会按预期产生正确的结果。例如本来要输入三个变量的值,结果刚输入两个变量的值就按下了Enter键来结束输入(输入错误)。
(4)scanf函数具有一定的学习价值,但在实际工作中几乎没有实用价值。