scanf篇
代码:
运行结果如下:
Q&A环节:
Q:去掉第六行红色框的空格字符,运行结果还是跟上面运行结果一样吗?
A:是的,
scanf
指定%s时会自动跳过所有空白字符(空格、制表符、换行符等),从而确保在不同字符串之间能够正确分隔。例如,hello world
会把hello
读取到str
,然后跳过空格后读取world
到str1
。即scanf中第一个参数为"%s%s"或"%s %s"两者运行效果一样。那么将第一个参数中间的空格换成逗号,如“%s,%s”呢,指示逗号作为两个字符串的分隔符,显然不适用与此处,因为%s控制格式时,逗号会作为字符串的一部分,无法区分什么时候的逗号为两个字符串中间的分隔符。
Q:在第三次运行的时候,输入了“123回车符”,scanf函数应该就运行结束了吧?
A:在平时,有种错觉就是觉得输入了回车,scanf就读取结束了。当scanf函数的第一个参数中,如果有两个或者更多的格式说明符时,格式说明符要求的输入未全部完成,敲回车不会结束输入过程。以上面代码为例,当输入“123回车”,那么此时只满足str有值,str1还没有,所以将继续处于输入状态,用户需继续输入。
补充
调用scanf,其执行时的某一过程是这样的,当用户键盘输入(假设输入的是“123回车”),将以Enter键作为此次结束输入操作,那么此时在操作系统的内核空间的行缓冲区中就会存在键盘输入的所有内容(连续的内存空间都是存的"123\n"),此时有符合%s的字符串了,那么"123"就从行缓冲区中提取出来了,然后会将"123",放至应用程序内存空间的变量空间中(上文例子的话就是存到str数组中),并自动在此字符串中添加一个字符串结束标志符'\0'。
证明程序如下图。
接上文
然后其中内核中的行缓冲区还会剩下'\n',只有"123"被提取走了。证明程序如下图
接上文
假如行缓冲区的内容是“\n123\n”, 当此时"123"被读走后,"123"前面的‘\n’就被刷掉了,而后面的‘\n’还在缓冲区。
----未完,后续内容稍后更新