先来讲讲大家最熟悉的gets()函数。
1.gets()函数不安全。
2.C11标准委员会已经将其废除,建议能不用尽量不用。
解释:
gets()函数的作用:它读取整行输入,直至遇到换行符,然后丢弃换行符,储存其余字符,并在其末尾添加一个空字符使其成为一个字符串。
听起来挺安全的,问题在于gets()函数不检查函数边界,有多少字符它就给你输入多少(来者不拒),这就造成了一个问题:缓冲区溢出(buffer overflow)。这意味着:如果他们有可能擦掉程序中的其他数据(即把数据放到了存储别的数据的地方并将其覆盖)这样就很容易出现问题。
gets()的替代品:
fgets()
get_s()
s_gets()
一. fgets()
fgets()通过第2个参数来限制读入的字符数来解决溢出问题。
函数专门用于处理文件输入,一般情况下不是很好用。
解释:
fgets()函数的第2个参数指明了读入字符的最大数量。如果参数是n,那么fgets()函数将读入n-1个字符,在最后加上空字符。或者读到遇到的第一个换行符为止。(也就是说:一旦读入的字符超过n-2将没有读入换行符)并将换行符储存在字符串中(注意与gets()对比)fgets()函数的第三个参数指明要读入的文件,如果读入从键盘输入的数据,则以stdin1(标准输入)作为参数,该标识符定义在stdio.h中。
#include
#define SIZE 10
int main ()
{
char words[SIZE];
fgets(words,SIZE,stdin);
fputs(words,stdout);
return 0;
}
fgets()函数的用法,大家体会一下。
二.gets_s()函数
gets_s()只从标准输入中读取数据,所以起形式为
gets_s(char *p,int n);//n表示其最多读取的数量,一般为数组大小
gets_s()读到换行符,会丢弃它。
如果输入行太长,gets_s()会丢弃该输入行的其余字符。
解释:
其优越性在于第三点:正常来讲,输入行中多出来的字符会被留在缓冲区中,成为下一次读取语句的输入。如果下一次读取的是int 或者double类型,就可能导致程序崩溃。但优点同时也是缺点,因为在其抛弃字符的同时并不会告知我们,一旦输入出现问题我们必须自己查找。
对于平时的应用大致了解这些就够了,主要了解一下用法,通常情况下我们是不会数组越界的。但是我想说的是fgets()和gets_()函数还有很多细节没有讨论,还有一些奇奇怪怪的用法等着我们去讨论。
stdin是C语言中标准输入流,一般用于获取键盘输入到缓冲区里的东西。 ↩︎