fgets和gets函数的区别

1. gets与fgets

  gets函数原型:char*gets(char*buffer);//读取字符到数组:gets(str);str为数组名。

  gets函数功能:从键盘上输入字符,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。

         读取的换行符被转换为null值,做为字符数组的最后一个字符,来结束字符串。

  注意:gets函数由于没有指定输入字符大小,所以会无限读取,一旦输入的字符大于数组长度,就会发生内存越界,

     从而造成程序崩溃或其他数据的错误。

  fgets函数原型:char *fgets(char *s, int n, FILE *stream);//我们平时可以这么使用:fgets(str, sizeof(str), stdin);

          其中str为数组首地址,sizeof(str)为数组大小,stdin表示我们从键盘输入数据。

  fgets函数功能:从文件指针stream中读取字符,存到以s为起始地址的空间里,知道读完N-1个字符,或者读完一行。

  注意:调用fgets函数时,最多只能读入n-1个字符。读入结束后,系统将自动在最后加'\0',并以str作为函数值返回。


2. 细节介绍

  1,上面说到gets函数无限读取,没有上限。但是有些资料介绍说它最多只能读取1024个,所以我写了下面代码测试一下

    (有兴趣的朋友可以测试一下(●'◡'●))

    经本人亲自测试第一次cnt = 2003,第二次cnt = 2086,第二次程序最后崩溃了,但是不能说明gets的读取上限为2086左右,

    因为程序崩溃是由于内存越界

  2,在来细说一下fgeis的用法,我们以char str[N];fgets(str, N, stdin);为例:

    fgets只能读取N-1个字符,包括最后的'\n',读完结束后系统将自动在最后加'\0'gets读完结束后系统自动会将'\n'置换成'\0')。

    说到这里就有俩种情况了:

    一:当你从键盘上输入<=N-1个字符(包括'\n')时,那么字符串str会以‘\n\0’结尾。这就造成了strlen(str)比你想象的大 1 ,

      当然你可以通过下面代码将'\n'去掉。

1 if(str[strlen(str) - 1] == '\n') {      // 去掉换行符
2     str[strlen(str) - 1] = '\0';   
3 }

    二:当你从键盘上输入>N-1个字符(包括'\n')时,那么字符串str会以'\0'结尾。

  3,在上面我们提到从键盘输入字符大于N的情况,这时gets和fgets就又有一些区别了,我们通过以下代码来测试一下:

复制代码
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 5
 4 
 5 int main()
 6 {
 7     char s1[N];
 8     char s2[N];
 9     fgets(s1, N, stdin);
10 //    gets(s1); 
11     if(s1[strlen(s1) - 1] == '\n') {      // 去掉换行符
12         s1[strlen(s1) - 1] = '\0';   
13     }
14 
15 //    fflush(stdin);                               //清空缓冲区
16     fgets(s2, N, stdin);
17 //    gets(s2);
18     if(s2[strlen(s2) - 1] == '\n') {      // 去掉换行符
19         s2[strlen(s2) - 1] = '\0';   
20     }
21 
22     printf("%s %s", s1, s2);
23     
24     return 0;
25 } 
复制代码

    当我们输入12345按下回车,直接就出来1234 5这样的结果。是不是与我们预想的不一样呢?我们单看结果,s1是1234

    s2是5。这是为什么呢?

    这就是fgets与gets的不同之处,我们第一个fgets只读取了1234,将5'\n'放入缓冲区中,当程序运行到第二个fgets时,

    它就会直接从缓冲区读取,直到遇到'\n'结束所以就会有这样的结果,此时s1是1234'\0',s2是5'\0'.我们应该怎么解决这种问题呢?

    我们可以在第二个fgets前加一句fflush(stdin),它是清除缓冲区的作用,大家可以试试,我就不截图了。

    上面我们是用fgets输入的,现在我们换成gets来输入,看看结果吧:

    说到这里就已经不是简单的gets与fgets的问题了,这涉及到了我们从键盘读入的数据在内存中是怎么显示的了,所以我只简单的说一下。

  在内存中s1是这样排序的

 

  '\0'
  6   
  5
  4 
  3 
  2 
  1

    当s2输入进来的时候会变成:

   '\0'
  6
5
4
3
   '\0'
  f
e
d
c
b
a

    所以输出的时候就会s1输出f,后遇'\0'结束,s2输出abcdef,后遇'\0'结束。


安冈乐花火
关注 关注
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gets,fgets,gets_s的区别分析
weixin_46200327的博客
08-07 3856
在最开始学习字符串时,我们最常用的输入字符串函数就是——gets(); 这个函数将输入缓冲区中的数据存储到字符型数组中,以换行符结束,并丢弃末尾的换行符添加一个空字符。他解决了scanf("%s",str);以空白符为截至的漏洞。 但是这个函数有一个致命的弱点——不能对数组溢出做出相应的处理。 我们都知道,在我们定义数组时先要确定数组的大小,系统会分配一段没被使用的连续空间给这个数组。在这片区域外,我们不知道其他的空间是否被使用,这就带来了一个问题——如果数组越界时,会存在安全隐患,但是gets函数并没有处
c语言中getsfgets,getsfgets函数及其区别,C语言getsfgets函数详解
weixin_36334262的博客
05-19 1826
每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的“互联网蠕虫”,它在 UNIX 操作系统的 finger 后台程序中使用一个 gets 调用作为它的攻击方式之一。很显然,对蠕虫病毒的实现来说, gets 函数的功劳不可小视。不仅如此,GCC 也不推荐使用gets和puts函数。那么,究竟是什么原因导致 gets 函数这么不招人待见呢?正确的语句是d (int)k%m28. 不能进...
getsfgets函数区别
weixin_30908103的博客
08-12 675
1. getsfgets   gets函数原型:char*gets(char*buffer);//读取字符到数组:gets(str);str为数组名。   gets函数功能:从键盘上输入字符,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。          读取的换行符被转换为null值,做为字符数组的最后一个字符,来结束字符串。   ...
fgetsgets区别
热门推荐
Angry 刀刀
09-07 3万+
在编程中发现getsfgets一些区别总结一下; 1、 fgetsgets安全,使用gets编译时会警告 为了安全,gets少用,因为其没有指定输入字符的大小,限制输入缓冲区得大小,如果输入的字符大于定义的数组长度,会发生内存越界,堆栈溢出。后果非常怕怕  fgets会指定大小,如果超出数组大小,会自动根据定义数组的长度截断。(redhat9.0实验并不是如此,不知为何,照样
C语言中输入函数(scanf()、fgets()和gets())的区别详解
01-01
大家都知道在C语言中,有三种主要的输入函数:scanf(),fgets()以及gets()。他们的使用方法及注意事项如下: 1.scanf() 它是一种格式化的输入方式,可一次性按照规定的格式输入多个数据域。 scanf函数是一个标准...
详解C语言gets()函数与它的替代者fgets()函数
09-01
本文将深入探讨两个常用的字符串读取函数:`gets()` 和其替代者 `fgets()`。`gets()` 函数曾经是C语言标准库中用于从标准输入(通常是键盘)读取一行文本的函数,但由于存在安全隐患,它在C99标准中被标记为不推荐...
fgets()和gets()函数区别
zwb8848happy的专栏
01-12 1万+
在编程中发现getsfgets一些区别总结一下: 1、fgetsgets安全! 为了安全,gets少用,因为其没有指定输入字符的大小,限制输入缓冲区得大小,如果输入的字符大于定义的数组长度,会发生内存越界,堆栈溢出。后果非常严重!  fgets会指定大小,如果超出数组大小,会自动根据定义数组的长度截断。 2、用strlen检测两者的输入的字符串长度,结果
C 语言中 fgetsgets 函数区别
最新发布
qq_43607992的博客
03-31 1583
gets 的声明为 char *gets(char *str),不需要指定读取字符数和文件流指针,它默认从标准输入流 stdin 中读取字符串。fgets 可以指定读取的字符数 n,因此它可以避免读取过多字符导致缓冲区溢出的问题,从而更加安全。需要注意的是,我们在调用 fgets 函数时,需要指定要读取的最大字符数,这里我们使用 sizeof(str) 来获取字符数组 str 的长度,以避免读取过多字符导致缓冲区溢出的问题。在上面的示例中,我们首先定义了一个字符数组 str,用于存储用户输入的字符串。
getsfgets区别
公孙莫言的博客
11-17 2348
简单来说 gets——从标准输入接收一串字符,遇到’\n’时结束,但不接收’\n’,把 ‘\n’留存输入缓冲区;把接收的一串字符存储在形式参数指针指向的空间,并在最后自动添加一个’\0’。 getchar——从标准输入接收一个字符返回,多余的字符全部留在输入缓冲区。 fgets——从文件或标准输入接收一串字符,遇到’\n’时结束,把’\n’也作为一个字符接收;把接收的一串字符存储在形式参数指针指向...
fgets()函数的使用
weixin_42404595的博客
07-03 551
fgets()函数的使用 虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据,换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这个问题,就会发生内存越界,所以编程时建议使用 fgets()。 fgets() 的原型为: 1 #include<stdio.h> 2 char *fgets(c...
fgets()与gets()的区别
u012780337的专栏
08-25 1215
getsfgets一些区别总结一下   1、fgets()比gets()安全        为了安全,gets()少用,因为其没有指定输入字符的大小,限制输入缓冲区得大小,如果输入的字符大于定义的数组长度,会发生内存越界,堆栈溢出。fgets()会指定大小,如果超出数组大小,会自动根据定义数组的长度截断。 2、用strlen()检测两者的输入的字符串长度不一样  get
fgetsgets区别
adlics_r的博客
11-14 730
1.fgets函数 功能:用于从文件中读取一字符串 函数原型char *fgets(char *buf, int bufsize, FILE *stream);参数 *buf: 字符型指针,指向用来存储所得数据的地址。 bufsize: 整型数据,指明存储数据的大小。 *stream: 文件结构体指针,将要读取的文件流。 返回值: 操作成功,返回的是msg的值,假如碰到文件结束或错误时
gets()、puts()和fgets()、fputs() 的区别
春秋繁露
10-21 2029
gets()、puts()和fgets()、fputs() 的区别
getsfgets区别.
zyipie的专栏
05-22 1078
在gcc里,使用gets会产生一条警告:  warning: the `gets' function is dangerous and should not be used. 曾经为了方便,就让它一直warning了,但是为什么gets是危险的呢。 在某国外论坛上看到这么一句话: In order to use gets safely, you have to know
写文章

热门文章

  • 关于websocket无法导入javax.websocket,等一系列问题 27661
  • ntohs函数的意思 14805
  • C语言中,我想在一个函数里用另一个函数的变量怎么办? 14553
  • fprintf函数的的用法 14001
  • strcmp函数的使用 12356

最新评论

  • DEV-C/C++ 编译时出现undefined reference to `WSAStartup@8'等错误解决办法

    m0_58211354: 有用谢谢

  • c语言中语句srand(time(NULL))什么意思。

    m0_67506765: 谢了

  • clreol函数

    路深: Dev C++无法编译

  • fprintf函数的的用法

    心火合滨: %s 字符串 -- 楼主请教一个输出文件的问题: 当定义一个结构体,该结构体中函数数组成员,向该数组成员中赋值字符串: fprintf(fp, "%s\n,"string); 这种做法会导致写入到该结体成员变量的字符串不带""双引号,导致编译出现error! 难道这个需要memcpy或者strcpy函数进行拷贝吗?

  • fprintf函数的的用法

    晖690: 和printf函数使用方法一样不?

最新文章

  • implement和extend的区别 在java中
  • java web编写SQL语句总结
  • Java 堆和栈的区别
2018年6篇
2017年33篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家奉节玻璃钢雕塑制作景观小品玻璃钢小鹿雕塑宣城浮雕玻璃钢雕塑厂家南京拉丝玻璃钢雕塑多少钱静安区玻璃钢雕塑公司金属雕塑玻璃钢沈阳市内玻璃钢雕塑兔子商丘小区玻璃钢雕塑厂家杭州商场组合玻璃钢花盆广州led发光玻璃钢雕塑厂家陕西优质校园玻璃钢景观雕塑临沂玻璃钢雕塑制作厂定做玻璃钢花盆厂家上海耐高温玻璃钢雕塑规格齐全深圳装饰商场美陈售价宁安玻璃钢价值观雕塑成都园林玻璃钢雕塑定制楚雄玻璃钢雕塑供应商嘉兴玻璃钢座椅雕塑重庆玻璃钢雕塑工程公司迪士尼玻璃钢企业吉祥物雕塑潜江玻璃钢考拉雕塑批发江苏季节性商场美陈销售公司广州玻璃钢花盆图片郑州玻璃钢雕塑有哪些安徽佛像玻璃钢雕塑制作沭阳玻璃钢雕塑厂家南通如东玻璃钢雕塑制品厂甘肃玻璃钢佛像雕塑张飞四川大型商场美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化