在C primer Plus书籍中gets()函数被称之为"不幸的",之所以被称之为不幸是因为get()函数如果在控制台上一直输入字符,如果超出数组容量,程序并不会检验报错,这也就意味着超出的字符串占用了尚未使用的内存空间。一旦超出的字符串在占用的时候正好占据了其它程序正在使用内存空间的时候就会立马报错!这种现象用编程术语的话来说就是:缓冲区溢出!为了弥补缓冲区溢出的现象,制定了C11的标准委员会楞是直接"废除"了gets()函数,从而采用fgets()函数将其取而代之,这也就是为什么gets()函数为什么被称之为"不幸的"原因所在。注意在这所说的废除只是不建议使用而已并不是真正意义上的废除,在使用方面来说gets()比fgets()函数要方便得多,只是在安全方面没有fgets()函数那么严谨。
如果你在一段代码中看到有gets的身影,那么有很大概率在后面的代码中看到puts的存在。俩者的关系时常是紧密相连、如胶似漆,如果没有看到puts的存在,那么很有可能是printf()函数将其替代了,gets()是输入函数,put()是输出函数,下面分别是gets()和put()函数使用说明:
(1)gets()函数是一个在控制台上输入多个字符,直到遇到回车键结束的函数.
(2)gets()函数如果在控制台一直输入字符,如果超出数组容量,程序并不会报错
(3)gets()函数在输入回车键'\n'字符的时候,并不会存储在字符串中,这也就意味着回车键'\n'字符在控制台上只有输入没有输出
(4)puts()与printf()函数使用方法类似,只不过puts是专门用于处理字符
(5)puts()为了弥补gets()函数丢弃的字符回车键字符'\n',在末尾会自动添加回车键字符'\n',所以这也就是为什么俩者的关系如此紧密相连的原因。
以下分别是gets()单独使用和gets()、puts()俩者共同使用方式,代码如下:
1、gets()
#include <stdio.h>
#define STLEN 5
int main(void){
char words[STLEN];
printf("请输入字符串:");
gets(words);//在控制台上输入HelloWorld
printf("%s",words);//在控制台上输出printf
return 0;
}
打印结果:
分析:这是gets()函数单独使用打印出来的结果,从结果可以看到gets()输入"HelloWorld"+回车键'\n',printf()打印出来的结果只是在控制台上显示出了"HelloWorld"并没有显示出回车键字符'\n'自动换行,这就充分说明了gets()函数在输入回车键'\n'字符的时候,并不会存储在字符串中,这也就意味着回车键'\n'字符在控制台上只有输入没有输出。
2、gets()、puts()俩者共同使用
#include <stdio.h>
#define STLEN 5
int main(void){
char words[STLEN];
printf("请输入字符串:");
gets(words);//在控制台上输入HelloWorld
puts(words);//在控制台上输出puts
return 0;
}
打印结果:
分析:(1)在上面说到gets()函数在单独使用的时候已经验证了在输出的时候会自动将回车键字符'\n'丢弃,从打印结果可以看到puts()为了弥补gets()函数自动将字符回车键'\n'补全
(2)gets()函数在控制台上输入"HelloWorld"+'\n'共11个字符,而words字符数组STLEN指定大小只有5的容量,由此可见当输入的字符容量超过了指定的容量,程序并不会马上检验报错。
文章开头说过C11委员会为了弥补缓冲区溢出的现象研发出了fgets()函数,从而替代了gets()函数,有了fgets()自然就有了fput()函数,俩者的关系在之前就说过了"如影随形",以下是fgets()和fput()函数使用说明:
(1)fgets可以指定输入字符的容量大小,若程序读取到超出了指定容量大小时便不再读取
(2)fgets读取到回车键字符'\n'时,会存储在字符串中。这点与gets()函数不一样
(3)fgets()和puts()函数分别比gets()和puts()函数多了个stdin、stdout。stdin"标准输入"、stdout"标准输出"
(4)当fgets()函数在末尾出添加了回车键字符作为结束时,如果选择使用puts()函数在控制台上输出内容,那么此时就会有俩个回车键'\n',一个是fgets()函数存储的字符、一个是puts()函数自带的回车键字符'\n'
以下是fgets()单独使用、fgets()和puts()、fgets和fputs()、超出指定容量使用方式: 代码如下:
1、fgets()
#include <stdio.h>
#define STLEN 12
int main(void){
char words[STLEN];
printf("请输入字符串:");
//fget三个参数使用说明:words字符数组名称、STLEN字符数组长度、stdin(标准输入)键盘上输入的数据
fgets(words, STLEN, stdin);
printf("%s",words);
return 0;
}
打印结果:
分析:fgets()函数在控制台上输入"HelloWorld"+'\n',在代码里面可以printf()函数并没有添加'\n',从打印结果可以看出fgets()函数将在控制台上输入的回车键字符'\n'保存了下来,与上面的gets()函数不一样。
2、fgets()和puts()
#include <stdio.h>
#define STLEN 12
int main(void){
char words[STLEN];
printf("请输入字符串:");
//fget三个参数使用说明:words字符数组名称、STLEN字符数组长度、stdin(标准输入)键盘上输入的数据
fgets(words, STLEN, stdin);
puts(words);
return 0;
}
打印结果:
分析:fgets()函数在控制台上输入"HelloWorld"+'\n',puts()函数在控制台上输出时自带回车键字符'\n',同时fgets()函数在输入字符的时候字符回车键'\n'结束时会存储在字符里面,所以控制台在显示的时候会有俩个回车。
3、fgets()和fputs()
#include <stdio.h>
#define STLEN 12
int main(void){
char words[STLEN];
printf("请输入字符串:");
//fget三个参数使用说明:words字符数组名称、STLEN字符数组长度、stdin(标准输入)键盘上输入的数据
fgets(words, STLEN, stdin);
fputs(words, stdout);
return 0;
}
打印结果:
分析:fputs()函数会根据fgets()函数输入的内容而依次显示出来,与上面的puts()函数自带回车键字符'\n'不一样
4、超出指定容量
#include <stdio.h>
#define STLEN 8
int main(void){
char words[STLEN];
printf("请输入字符串:");
//fget三个参数使用说明:words字符数组名称、STLEN字符数组长度、stdin(标准输入)键盘上输入的数据
fgets(words, STLEN, stdin);
fputs(words, stdout);
return 0;
}
打印结果:
分析:该段代码与第三段代码几乎一样,只是把第三段开头的代码#define STLEN 12修改成了8,在控制台上输入的"HelloWorld"+'\n'共11个字符,所以当控制台上输入的字符超出了指定容量时,在显示的时候只会显示出指定容量-1,共7个字符。
在初次接触gets()函数时,不由地想起了scanf()函数,因为俩者都是在控制台上输入,然而俩者的区别就在于:
(1)gets()函数输入的类型只能是字符串,并且可以是多个字符串
(2) scanf()函数可以输入多个不同类型的数据,输入的次数根据scanf()里面有多少个参数来决定
以上就是gets()、puts()、fgets()、fputs()的函数使用方式以及区别说明。