先看每个函数的原型:
gets() (代表gets string),因为字符串没有预订的长度,所以gets需要知道何时读取
可以结束(注意,是从stdin流中的)解决的办法是读字符串,直到遇到一个换行符\n。
然后在这些字符传后面添加一个空字符\0,然后返回。这个\n它读取后但会丢弃。
故gets是会读取\n但不会存储。
gets的一个不足是它不检查预留的存储区是否能够容纳实际输入的数据。多出来的字符简单地溢出
到相邻的内存区。(UNIX中的蠕虫病毒就利用了这点,后来的系统代码就不是用gets了,因此对应重要的编程
应该使用fgets而不是gets)
fgets改进了这个问题,它让你指定最大读入字符。由于fgets是为文件I/O额设计的,它在处理键盘输入时候就不如gets那么
方面。 它与gets相比有三方面的不同。
1,它需要第二个参数来说明最大的读入字符数。如果这个参数是n,那么fgets就会读取最多n-1个字符或者
读完遇到一个换行符为止。(它会自动添加\0)
2,如果fgets读到换行符,就会把它存到字符串里面,而不是像gets样丢弃它。
3,它还需要第三个参数来说明读那一个文件。从键盘上读取数据时(实际上是从stdin流中读取),可以使用stdin作为该参数。
有这个例子可以很显然地看出来,fgets把换行符也放入了字符串。
puts
使用很简单,只需要给出字符串的地址即可。
puts在显示字符串的时候,自动给后面添加一个换行符。(即遇到停止时候,自动添加一个换行符)
但puts如何知道何时停止呢?,遇到空字符\0就会停止,所以应该确保输出的地址中的内容有有空字符的存在。(一般字符串数组
都自动添加了,我说的是字符串数组而不是字符数组,字符数组是没有添加的,如果有puts输出字符数组,那么
结果不可预期,因为不知道身边吗时候i会遇到\0)
fputs
1,fputs是面向文件的版本,需要第二个参数来说明要写入的文件,可以使用stdout为参数来表示输出到屏幕。
2,与puts不同,fputs并在结尾自动添加换行符。
这段话描述得很详细了。。。
符:转载(不知道是不是对的,但可以参考)
- 总结:
- ①scanf既不吸收<换行符>,也不清除<换行符>,下次的函数还会遇到<换行符>。
- 如果scanf在开头遇到前次函数留下的' ',scanf一律跳过,继续运行;如果在中间遇到' ',scanf将会停止。
- 如果scanf在开头遇到前次函数留下的<换行符>,scanf也会跳过,继续运行(gets会停下来)
- ②gets一遇到<换行符>就会退出,所以scanf后面的gets总是会直接退出。
- gets不会吸收<换行符>,但是会清除缓冲区中<换行符>,下次的函数就不会遇到<换行符>;
-
- 应用:
- 对于<换行符>,scanf肯定会留下,gets肯定不会留下,fgets可能会留下也可能不留下
- 所以保险的办法是在每一个scanf的后面都加上getchar(),如下:
- scanf(...);
- getchar();
- */
-