c语⾔gets()函数与它的替代者fgets()函数
在c语⾔中读取字符串有多种⽅法,⽐如scanf() 配合%s使⽤,但是这种⽅法只能获取⼀个单词,即遇到空格等空字符就会返回。如果要读取⼀⾏字符串,⽐如:
I love BIT
这种情况,scanf()就⽆能为⼒了。这时我们最先想到的是⽤gets()读取.
gets()函数从标准输⼊(键盘)读⼊⼀⾏数据,所谓读取⼀⾏,就是遇到换⾏符就返回。gets()函数并不读取换⾏符'\n',它会吧换⾏符替换成空字符'\0',作为c语⾔字符串结束的标志。
gets()函数经常和puts()函数配对使⽤,puts()函数⽤于显⽰字符串,并⾃动在字符串后⾯添加⼀个换⾏标志'\n'
gets()函数存在⼀个严重的缺陷,这个缺陷就是:它不会检查数组是否能够装的下输⼊⾏:
⽐如:
我们定义了⼀个数组char src[5],这时候我们调⽤gets(src),来从标准输⼊读取字符串,我们看到gets()函
数的参数为数组名,我们都知道,数组名就相当于⼀个指针,也就是数组的⾸地址。这时如果我们的输⼊⼤于5个字符,⽐如 I love BIT,gets()函数会从src所指地址开始,依次填⼊每个字符,但是src只分配了5个字节的空间,填满这五个空间后,gets()函数就会访问未被分配的内存空间,如果这⽚空间已经存有数据,这时程序就会发⽣错误,⽽中断。
正式由于gets()函数的这个缺陷,在C99标准中,已经不再建议使⽤gets()函数,⽽在C11中更是直接抛弃了这个函数。
gets()被抛弃,那我们⽤什么来代替它的功能呢?
C11标准新增了gets_s()函数可以代替gets()函数,但是,该函数是stdio.h输⼊输出函数系类中的可选扩展,因此,即使编译器⽀持C11标准,也有可能不⽀持gets_s()函数。
其实我们可以⽤c语⾔中的fgets()函数来代替gets()
我们先看⼀下函数原型声明:
char *fgets(char *buf, int bufsize, FILE *stream);
注意⼀下第⼆个参数bufsize,这个参数就限制了读取的字符的个数,这就可以解决gets()函数的缺陷。字符串函数gets怎么重新定义
我们知道fgets() 函数主要⽤于读取⽂件,如果要读取键盘,则stream参数应该为stdin,
需要注意的是,如果bufsize设置为n,那么fgets()函数最多读取n-1个字符,之所以⽤“最多”这个词是因为,如果在之前遇到了换⾏符,fgets 函数也会返回。
还有⼀点就是,fgets()函数会读取换⾏符(这⼀点和gets函数不同),当读取结束后,fgets函数会为buf在末尾添加⼀个空字符作为字符串的结束。
可以看⼀个简单的⼩例⼦:
#include <stdio.h>
#include <stdlib.h>
#define LEN 6
int main(int argc,char* argv[])
{
char src[LEN];
printf("please enter:\n");
fgets(src,LEN,stdin);
printf("your enter is:\n");
fputs(src,stdout);
}
在这个程序中,我把数组的长度设置为6,先看⼀组输⼊和输出:
输⼊为zhan和回车('\n'),⼀共五个字符,fgets会读取这五个字符,然后在末尾添加字符串结束标志'\0';
我们知道fputs()函数并不会⾃动添加换⾏,但是输出结果却换⾏输出了,这就说明了fgets()
函数是会读取换⾏符的。
在看⼀组输⼊输出:
这次我输⼊了zhang和回车换⾏,fgets函数依然是读取5个字符(LEN-1个),这时fgets()读⼊zhang,已经是五个字符了,所以回车换⾏并不会读⼊,最后fgets()添加字符串结束标志'\0',所以我们看到输出时,并没有换⾏输出,⽽是和zhang在同⼀⾏。
最后看⼀组输⼊和输出:
相信不⽤解释⼤家也都明⽩了。
总结⼀下就是:
gets函数没有限制读⼊的个数,这很可能会导致程序向未知的内存空间写⼊数据,⽽导致程序出错。
fgets函数中第⼆个参数限制了读取的个数,这也解决了gets函数存在的问题,但要注意fgets函数只会读取n-1个字符(如果遇到换⾏符会更少),并在最后添加字符串结束标志,⽽且,fgets也会将换⾏符读⼊。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论