这篇文章要探讨的是“fgets()函数的详解以及使用时需要注意的一些细节”。涉及fgets()函数的应用和需要注意的问题。属于C语言基础篇(持续更新)。

fgets()(函数原型:char *fgets(char *restrict str, int size, FILE *restrict stream))

这个函数原型不太好看出个所以然来,可以理解为(char *fgets(“容器的地址”, “容器的大小”, “从哪里读取”))


一般用法:

char a[100] = {0};
fgets(a, 100, stdin);

通俗来讲的话,fgets()函数的作用就是用来读取一行数据的。但要详细且专业的说的话,fgets()函数的作用可以这么解释:从第三个参数指定的流中读取最多第二个参数大小的字符到第一个参数指定的容器地址中。在这个过程中,在还没读取够第二个参数指定大小的字符前,读取到换行符'\n'或者需要读取的流中已经没有数据了。则提前结束,并把已经读取到的字符存储进第一个参数指定的容器地址中。

在正常情况下fgets()函数的返回值和它第一个参数相同。即读取到数据后存储的容器地址。但是如果读取出错或读取文件时文件为空,则返回一个空指针。


fgets()函数的运行流程大概是这样子的:

当系统调用这个函数的时,系统便会阻塞等待用户的输入,直到用户输入回车符’\n’才返回程序。然后用户输入的内容会被系统放进输入缓存区里面,fgets()函数便会进来读取其“第二个参数减1(为什么减1后面说)”个字节存进它第一个参数指向的内存地址中,如果在还没读取够需要的字节大小前读取到换行符’\n’则提前返回。


fgets()函数的注意事项1

fgets()函数的最大读取大小是其“第二个参数减1”,这是由于字符串是以’\0’为结束符的,fgets()为了保证输入内容的字符串格式,当输入的数据大小超过了第二个参数指定的大小的时候,fgets()会仅仅读取前面的“第二个参数减1”个字符,而预留1个字符的空间来存储字符串结束符’\0’

测试代码

#include <stdio.h>
int main(void)
{
    char a[10] = {0};
    printf("你的输入:");
    fgets(a, 4, stdin);
    //printf("%s\n", a);//下面这句的输出和这句是一样的
    printf("printf(\"%%s\\n\", a)%c==>%s\n", ';', a);
    return 0;
}

运行效果:

在这个例子中,fgets()的第二个参数是4,所以它最多只能存储输入的(4-1 = 3)个字符进第一个参数指向的地址空间里面。输入“abcde”,数组a[]中只有“abc”。


fgets()函数的注意事项2

fgets()函数的眼里,换行符’\n’也是它要读取的一个普通字符而已。在读取键盘输入的时候会把最后输入的回车符也存进数组里面,即会把’\n’也存进数组里面,而又由于字符串本身会是以’\0’结尾的。所以在输入字符个数没有超过第二个参数指定大小之前,你输入n个字符按下回车输入,fgets()存储进第一个参数指定内存地址的是n+2个字节。最后面会多出一个’\n’和一个’\0’,而且’\n’是在’\0’的前面一个(\n\0)。

测试代码:

#include <stdio.h>
int main(void)
{
    char a[10] = {0};
    printf("你的输入:");
    fgets(a, 10, stdin);
    //printf("%s\n", a);//下面这句的输出和这句是一样的
    printf("printf(\"%%s\\n\", a)%c==>%s\n", ';', a);
    for(int i=0; i<10; i++)
    {
        if(a[i] == '\n')
            printf("a[%d]是换行符'\\n'\n", i);
        if(a[i] == '\0')
            printf("a[%d]是字符串结束符'\\0'\n", i);
    }
    return 0;
}

运行效果:


在这个例子中,由于输入的字符小于参数2指定的最大读取字符数,所以fgets()函数会把换行符’\n’也储存进数组a[]里面,在运行界面的第三行哪里换了两次行,就是由于这个多出来的换行符’\n’和我输出代码中的换行符’\n’共同作用的结果。


fgets()函数的注意事项3

fgets()函数只负责读取,并不会事先清空参数1指向的地址内存。读取到的字节会覆盖原地址储存,但没有覆盖到的内容还是保持原样。

测试代码:

#include <stdio.h>
int main(void)
{
    char a[10] = {'1','1','1','1','1','1','1','1','1','1'};
    printf("你的输入:");
    fgets(a, 10, stdin);
    //printf("%s\n", a);//下面这句的输出和这句是一样的
    printf("printf(\"%%s\\n\", a)%c==>%s\n", ';', a);
    for(int i=0; i<10; i++)
    {
        if(a[i] == '\n' || a[i] == '\0')
            printf("a[%d] = '\\%c'", i, a[i]=='\n'?'n':'0');
        else
            printf("a[%d] = %c", i, a[i]);
        printf("\n");
    }
    return 0;
}
 

运行结果:


fgets()函数的注意事项4

在用fgets()函数读取键盘输入的时候,如果输入多于其“第二个参数减1”个字符大小的数据,fgets()只会读取走前”第二个参数减1”个字符,多余的字符残留在输入缓存区里面。如果不清空,可能会影响下次输入。

测试代码:

#include <stdio.h>
int main(void)
{
    char a[4] = {0};
    char b[10] = {0};
    printf("存进a的输入:");
    fgets(a, 4, stdin);
    for(int i=0; i<4; i++)
        printf("a[%d] = %c\n", i, a[i]);
    printf("存进b的输入:");
    fgets(b, 10, stdin);
    printf("这里没有阻塞等待输入,而是直接跳过了\n");
    //printf("%s", a);//下面这句的输出和这句是一样的
    printf("printf(\"%%s\", b)%c==>%s", ';', b);
    return 0;
}
 

运行结果:

在这个例子中,输入“abcde”之后,数组a[]读取走“abc”之后,代码运行到第11行的时候并没有停下来等待用户的输入,而是直接读取了还留在缓存区里面的“de\n”,读取到‘\n’之后返回,所以我最后一行的输出代码中并没有加上换行符’\n’,因为数组b[]中已经包含有换行符’\n’了。


fgets()函数的注意事项5

遇到再更新。。。


零BUG是原则性问题。

fgets()函数的详解-使用技巧-C语言基础相关推荐

  1. fgets()函数的详解以及使用时需要注意的一些细节-C语言基础

    这篇文章要探讨的是"fgets()函数的详解以及使用时需要注意的一些细节".涉及fgets()函数的应用和需要注意的问题.属于C语言基础篇(持续更新). fgets()(函数原型: ...

  2. 【转载】fgets函数用法详解

    虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据,换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这 ...

  3. JVM垃圾回收面试题详解,java开发语言基础知识

    所以这种算法已经没人用了. 2.2 可达性分析法 2.2.1 什么是可达性 可达性分析法就是目前的主流算法,也是java正在使用的算法. 它的做法是,通过一系列被称为"GC Roots&qu ...

  4. 用计算机函数查找,Excel查找函数Vlookup详解及应用示例-excel技巧-电脑技巧收藏家...

    Excel查找函数Vlookup详解及应用示例 招如其名.此招用来在一个茫茫的数据源中,自动让电脑找出你要的某个数据的相关资料并填在指定的地方.也是就是,可以让电脑在一个表格或指定的一个区域中查找某一 ...

  5. 如何使用计算机Excel公式if,Excel条件函数If详解及应用示例-excel技巧-电脑技巧收藏家...

    Excel条件函数If详解及应用示例 此招用来对某一条件执行的真假值进行判断,根据逻辑计算的真假值,返回不同结果.如果结果为真,则返回一个真,如果为假,则返回另一值,可谓左右逢源. 使用语法 IF(l ...

  6. python text函数_python可视化text()函数使用详解

    python可视化text()函数使用详解 这篇文章主要介绍了python可视化text()函数使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考 ...

  7. python中import re_Python3中正则模块re.compile、re.match及re.search函数用法详解

    本文实例讲述了Python3中正则模块re.compile.re.match及re.search函数用法.分享给大家供大家参考,具体如下: re模块 re.compile.re.match. re.s ...

  8. EXCEL公式VLOOKUP函数用法详解

    EXCEL公式VLOOKUP函数用法详解 示例下载 VLOOKUP函数 在表格或数值数组的首列查找指定的数值,并由此返回表格或数组中该数值所在行中指定列处的数值. 这里所说的"数组" ...

  9. sqlserⅴer随机函数_SQL server的随机数函数rand()详解

    SQL server的随机数函数rand()详解 from:http://tieba.baidu.com/f?kz=607363268 在SQL Server中,有个随机函数rand(),有不少新手可 ...

最新文章

  1. 枚举 ---- B. RPG Protagonist[Educational Codeforces Round 94 (Rated for Div. 2)]数学枚举
  2. 开源you-get项目爬虫,以及基于python+selenium的自动测试利器
  3. 2020-11-11(C语言下JNI开发hello过程)
  4. IntelliJ IDEA 添加项目后编译显示包不存在的解决方案
  5. oracle usehash,/*+use_hash(t1 t2)*/的神奇
  6. 计算机中的数(一):数在计算机中的表示
  7. 第1篇:Flowable快速工作流脚手架Jsite_克隆项目
  8. php怎么把日志推送过去_实践 | 基于Flink的用户行为日志分析系统
  9. [SAP ABAP开发技术总结]以二进制、字符模式下载文件
  10. SpringBoot-15-之整合MyBatis-注解篇+分页
  11. JDK官网下载+JDK环境安装+hadoop环境配置
  12. java模拟器触屏_jar模拟器-jar模拟器触屏版电脑版下载_暂未上线|好特下载
  13. 沧小海基于xilinx srio核的学习笔记之第三章 xilinx srio核介绍(三)核配置
  14. iphone 4 微信版本过低
  15. 加密聊天应用依然安全
  16. JAVA生成热点图,JAVA 后端生成热力图图片返回
  17. Actor编程模型——简介
  18. 嵌入式技术栈之spi协议的时序
  19. 云计算与大数据---21大数据张舒
  20. Amazon Redshift - 基本介绍

热门文章

  1. 20来行的Python拼写检查器
  2. HM代码-码控(1)-乱七八糟的初始化
  3. 既生 synchronized 何生 JUC 的 显式 locks ?
  4. C++多线程编程资料清单
  5. 基于SSM快递取件管理系统
  6. 计算机版的微信的功能是什么,赶紧更新你的PC版微信:这几项新功能你绝对想要...
  7. python单选按钮取消_取消选中单选按钮-PyQt4
  8. 在jupyter安装jieba出错ModuleNotFoundError: No module named ‘jieba‘的解决办法
  9. 权限系统--前后端完全分离
  10. QT自定义简单表盘(完整代码)