首先分享我在open judge看到的一道题目
从题干上理解还是不难的,但让我卡住的地方是字符串的输入部分
##下面给出我的第一次代码
可以看到,字符数组a中存储的是其实是一个换行键,那是哪里来的换行呢?直接给我干沉默了,为啥我之前用scanf函数没有遇到这个问题呢?于是我找了找scanf函数与gets函数输入字符串的区别。
1. scanf函数
scanf函数的一大特点就是要匹配对应的格式控制字符%s(我这里只研究字符串的输入),以及要用&char读取字符数组首地址,传递指针。回到上面的问题,为什么不会出现scanf读取换行字符呢,我们来测试一下。
这里可以看到,明显我敲下abc后会再敲一个回车,这个回车会保留在缓冲区域内,按道理来说,这个回车会被第二个scanf函数读走,所以就不会让你输入def了,真相真的是这样吗?显然不是。
你真的了解我们的回车键吗?
这里我们就需要了解scanf函数的读取结束标志,我们知道,当我们敲下键盘上的回车时,实际上执行了两个指令(http://t.csdn.cn/dQ3FE 附上链接 不知道的可以去看看),分别是回车(\r)与换行(\n),先执行回车 再执行换行!
与此同时,scanf函数读到换行才会终止,也就是说,我之前的假设大错特错,缓冲区此时没有任何字符!
2.gets函数
在c语言中,gets函数需要调用<string.h>库。同时,gets函数与scanf不同,他读到回车键就会停止读取!回到我上面关于题目的代码,所以执行完scanf之后,换行键(\n)也就停留在缓冲区。所以在puts(a)时换了一次行,相当于printf("\n")。
3.解决方案
我的想法时将缓冲区的(\n)用getchar()提取出来,于是最后的代码就是这样
理论上应该是没有问题的,咳咳咳,可是 c了蛋了
原因:len没有初始化,导致后面数组可能越界,稍微提一嘴,其实可以用strlen函数得到len
小结:输入字符串时,使用scanf函数时注意不能带空格(scanf遇到空格和回车换行结束),
使用gets时注意换行,使用getchar将缓冲区清空(若缓冲区有很多字符,可使用for循环,结束条件为读到'\0'),当scanf与gets混着用时更要谨慎哦