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

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

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

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

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

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

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

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

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

    s2是。这是为什么呢?

    这就是fgets与gets的不同之处,我们第一个fgets只读取了,将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. PHP中fopen,file_get_contents,curl函数的区别

    PHP中fopen,file_get_contents,curl函数的区别 1.fopen/file_get_contents每次请求都做DNS查询,并不对DNS的信息进行缓存,而curl会对DNS的 ...

  2. fgets函数

    打开文件 fopen("需要打开的路径") 然后使用fgets函数读取行 #include <stdio.h> #include <stdlib.h> #i ...

  3. php正规则表达式学习笔记(几个常用函数的区别)

    preg_mache()函数和 preg_mache_all()函数的区别: preg_mache()只会匹配规则中的字符一次, preg_mache_all()会匹配符合条件的所有字符! 例子对比: ...

  4. c语言中的fgets函数

    fgets()函数用于从文件流中读取一行或指定个数的字符,其原型为: char * fgets(char * string, int size, FILE * stream); 参数说明:string ...

  5. SQL表值函数和标量值函数的区别

    SQL表值函数和标量值函数的区别 写sql存储过程经常需要调用一些函数来使处理过程更加合理,也可以使函数复用性更强,不过在写sql函数的时候可能会发现,有些函数是在表值函数下写的有些是在标量值下写的, ...

  6. exit()与_exit()函数的区别(Linux系统中)

    注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1或者1,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXI ...

  7. fork 函数 和vfork 函数的区别

    问题描述:         fork 函数 和vfork 函数的区别 问题解决: fork函数使用: 注:         以上printf 属于标准IO库带缓冲,如果标准输出链接到终端设备,则它是行 ...

  8. sql - sum() 和 count() 函数的区别

    对sql一直都是蜻蜓点水,突然也觉得对这两个函数的区别有点朦胧,查了一下,在这里说一下: sum():主要用于累加求和. count():主要用于行(记录)的统计.

  9. php中strstr、strrchr、substr、stristr四个函数的区别总结

    php中strstr.strrchr.substr.stristr四个函数的区别总结 投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-09-22我要评论 这篇文章主要介绍了php ...

随机推荐

  1. Foundation 框架

    1.框架是有许多类,函数,方法,文档按照一定的逻辑组织起来的集合 2. Foundation框架是所有框架的基础 3.术语cocoa指的是foundation框架和appication kit框架 4 ...

  2. 反编译C#的dll文件并修改,再重新生成dll

    1.把dll文件导入到ildasm工具中,ildasm是由微软提供的.net程序反编译工具,位于“C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A ...

  3. HDU 1039 -Easier Done Than Said?

    水水的 #include <iostream> #include <cstring> using namespace std; ]; bool flag; int vol,v2 ...

  4. HDU1789(Doing Homework again)题解

    HDU1789(Doing Homework again)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时 ...

  5. javascript实现当前页导航激活

    html <ul id=”nav”> <li><a href=”http://www.daqianduan.com/”>首页</a></li> ...

  6. Android_实现静默安装和卸载应用

    转:http://www.cnblogs.com/ondream/archive/2012/04/13/2446138.html 前段时间做了一个批量安装卸载应用程序的小应用,由于安装卸载应用程序的部 ...

  7. Ghost win7 系统安装(虚拟机)

    1.将Ghost.iso添加到数据存储iso文件中,启动虚拟机,根据相关提示,文件格式化系统硬盘,完成操作后关机: 2.进入BIOS,设置从CDROM启动系统(否则系统会提示找到引导文件): 3.将系 ...

  8. 外网如何访问本地tomcat web服务器【转】

    转自:http://jingpin.jikexueyuan.com/article/49159.html 外网如何访问本地tomcat web服务器 作者: XHKJOE 发布时间:2015-07-1 ...

  9. chrome可以登陆账号的hosts文件

    原文地址: 百度 chrome吧 http://zhidao.baidu.com/question/1818688600091435508.html?qq-pf-to=pcqq.group http: ...

  10. 普林斯顿大学算法课 Algorithm Part I Week 3 比较器 Comparators

    比较器接口(Comparator interface):用可选顺序(alternate order)进行排序 public interface Comparator<key> int co ...