gets和fgets函数的区别

来源:互联网 发布:linux输入法切换快捷键 编辑:程序博客网 时间:2024/06/11 15:00

一、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,在来细说一下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’去掉。
example:
123abc
fgets(s,10,fp);
此时,读入七个字符,123abc\n,实际上还有最后的’\0’,所以,strlen(s)=7; 如果要去除末尾的\n,s[strlen(s)-1]=’\0’;便可。

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

二:当你从键盘上输入>N-1个字符(包括’\n’)时,那么字符串str会以’\0’结尾。
example:
123abc
char s[5];
fgets(s,5,fp);
这时读入4个字符,123a,并没有换行符,所以strlen(s)=4.
  3,在上面我们提到从键盘输入字符大于N的情况,这时gets和fgets就又有一些区别了,我们通过以下代码来测试一下:

#include <stdio.h>#include <string.h>#define N 5int main(){    char s1[N];    char s2[N];    fgets(s1, N, stdin);  //  gets(s1);     if(s1[strlen(s1) - 1] == '\n') {      // 去掉换行符        s1[strlen(s1) - 1] = '\0';      }  // fflush(stdin);                               //清空缓冲区    fgets(s2, N, stdin); /// gets(s2);    if(s2[strlen(s2) - 1] == '\n') {      // 去掉换行符       s2[strlen(s2) - 1] = '\0';       }    printf("%s %s", s1, s2);    return 0;}

这里写图片描述
当我们输入12345按下回车,直接就出来1234 5这样的结果。是不是与我们预想的不一样呢?我们单看结果,s1是1234,s2是5。这是为什么呢?
 这就是fgets与gets的不同之处,我们第一个fgets只读取了1234,将5’\n’放入缓冲区中,当程序运行到第二个fgets时,它就会直接从缓冲区读取,直到遇到’\n’结束所以就会有这样的结果,此时s1是1234’\0’,s2是5’\0’.我们应该怎么解决这种问题呢?我们可以在第二个fgets前加一句fflush(stdin),它是清除缓冲区的作用,大家可以试试,我就不截图了。

原创粉丝点击