• gets和fgets函数的区别


    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个字符。读入结束后,系统将自动在最后加'',并以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个字符,包括最后的' ',读完结束后系统将自动在最后加''gets读完结束后系统自动会将' '置换成'')。

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

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

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

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

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

      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] == '
    ') {      // 去掉换行符
    12         s1[strlen(s1) - 1] = '';   
    13     }
    14 
    15 //    fflush(stdin);                               //清空缓冲区
    16     fgets(s2, N, stdin);
    17 //    gets(s2);
    18     if(s2[strlen(s2) - 1] == '
    ') {      // 去掉换行符
    19         s2[strlen(s2) - 1] = '';   
    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' '放入缓冲区中,当程序运行到第二个fgets时,

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

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

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

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

      在内存中s1是这样排序的

      ''
      6   
      5
      4 
      3 
      2 
      1

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

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

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

     

     

     

  • 相关阅读:
    纪念时至今日才学会的命令行
    面向对象程序设计寒假作业2
    面向对象程序设计寒假作业1
    POJ 2104 K-th Number
    HihoCoder 1325 平衡树·Treap
    HihoCoder 1079 离散化
    POJ 2135 Farm Tour
    Luogu P1231 教辅的组成
    洛谷 P3410 拍照
    洛谷 P3370 【模板】字符串哈希
  • 原文地址:https://www.cnblogs.com/aexin/p/3908003.html
Copyright © 2020-2023  润新知