http://www.cnblogs.com/aexin/p/3908003.html

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个,所以我写了下面代码测试一下

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

 1 //测试gets最多读取字符是否超过1024
 2 #include <stdio.h>
 3 #include <string.h>
 4
 5 int main()
 6 {
 7     char str[2048];       //听说gets最多可以读取1024个字符,我们设定一个2048的数组
 8     gets(str);            //从键盘输入大于1024个字符
 9     int cnt;
10     printf("cnt = %d", strlen(str));   //cnt的值就是数组元素个数,是否大于1024呢???
11
12     return 0;
13 }

    经本人亲自测试第一次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'结束。

gets fgets 区别相关推荐

  1. c语言中gets 、getchar 、fgets 、scanf的用法

    原文地址:https://www.cnblogs.com/-lyric/p/5118666.html http://c.biancheng.net/view/379.html gets--从标准输入接 ...

  2. gets 、getchar 、fgets 、scanf的用法

    原文地址: http://c.biancheng.net/view/379.html https://www.cnblogs.com/-lyric/p/5118666.html 1.gets   从标 ...

  3. qtablewidget翻页禁止_PyQt—QTableWidget实现翻页功能

    主要使用QTableWidget中的三个函数实现: verticalScrollBar().setSliderPosition() 设置当前滑动条的位置 verticalScrollBar().max ...

  4. C语言scanf fgets,C语言中输入函数(scanf()、fgets()和gets())的区别详解

    前言 大家都知道在C语言中,有三种主要的输入函数:scanf(),fgets()以及gets().他们的使用方法及注意事项如下: 1.scanf() 它是一种格式化的输入方式,可一次性按照规定的格式输 ...

  5. fgets和scanf的区别

    fgets和scanf的区别 1.测试使用scanf的一个例子: [cpp] view plaincopyprint? #include "stdio.h" #include &q ...

  6. gets与fgets,puts与fputs区别

    一.gets与fgets //gets函数很危险,gets没有指定输入字符的大小,限制输入缓冲区的大小,如果输入的字符大于定义的数组长度,会发生内存越界,堆栈溢出.后果严重! 对于 gets 函数,它 ...

  7. gets和fgets函数及其区别,C语言gets和fgets函数详解

    gets和fgets函数及其区别,C语言gets和fgets函数详解 每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的"互联网蠕虫",它在 UNIX 操作系统的 ...

  8. C语言中fgetc()、fgets()之间的区别

    在学习文件那一快关于读写文件中的字符让我折腾了一阵子,总是把这几个函数混淆,今天有时间就整理下,并分享下个人的心得,希望对大家有帮助. 1.fgetc() 和 fgets() 之间的区别 fgetc ...

  9. fgets和gets的区别

    在编程中发现gets和fgets一些区别总结一下: 1. fgets比gets安全,使用gets编译时会警告 为了安全,gets少用,因为其没有指定输入字符的大小,限制输入缓冲区得大小,如果输入的字符 ...

最新文章

  1. [Java in NetBeans] Lesson 17. File Input/Output.
  2. Codeforces Round #462 (Div. 2)
  3. macos mojave_如何修复macOS Mojave上的模糊字体(使用亚像素抗锯齿)
  4. yeoman_具有Spring Boot和Yeoman的单页Angularjs应用程序
  5. Android Canvas类介绍和Android Draw Rect 坐标图示
  6. net java互相调用_Java与.NET的WebServices相互调用
  7. ZOJ-3953 Intervals,t
  8. 扶贫计算机考试试题,计算机基础知识试题1.doc
  9. 国内外大数据经典案例研究
  10. 【OpenCV】58 二值图像分析—寻找最大内接圆
  11. 数据库建模多表一对多和多对一、一对一、多对多
  12. ​Debug如何引流(降龙十八掌)
  13. 如何在Microsoft PowerPoint中绘制和操纵箭头
  14. asp.net word操作
  15. JAVA 技术方向赏金任务-快递 E 栈训练任务
  16. 【无标题】C语言连续输出输入语句执行跳过的问题
  17. 服务无法注册到注册中心解决
  18. OJ题库1015: 计算时间间隔
  19. 《Android开发自我整理知识——简介及学习资料链接》
  20. 《git-修改.gitignore后使其配置生效方法》---记录几个命令而已

热门文章

  1. Delphi 关键 重启 注销
  2. nios pio interrupt 的使能
  3. python可以自动写文章吗_让python来告诉你神奇的操作,如何实现文章自动化
  4. c语言如何在文件中间插入数据,急求如何将下列C语言程序数据存储到文件中?...
  5. java soot_正确执行3个地址代码的SOOT API
  6. cmd如何刷新MySQL数据库_怎样在cmd中用命令操作MySQL数据库 需要技巧
  7. mysql 5.6.23免安装_mysql5.6.23免安装配置
  8. NYOJ 35表达式求值
  9. Scala中的while循环
  10. mcq 队列_MCQ | 量子密码学