fgets的使用方法详解

FATFS 初学之 f_gets/ f_putc/ f_puts/ f_printf 详见:嵌入式大讲堂 f_gets: 1 /*-----------------------------------------------------------------------*/ 2 /* Get a string from the file */ 3 /*--------... 阅读详情
AI摘要

本文介绍了fgets函数在C语言中的基本语法、使用示例,以及它与gets函数的主要区别,强调了fgets的安全性和可控制性,提倡在编程中使用fgets以避免潜在的越界问题。

fgets的使用

前言(吹水,不看也罢)

鼠鼠今天在B站上大学的时候,做到了一题倒序输出字符串的题,本着能开摆就不学新内容的精神,本鼠决定使用之前学过的gets() 函数作为输入,但是在编译的时候遇到了这样一个警告(之前好像是提示该函数被弃用,升级VS版本后直接提示未定义,见下图),程序能跑,但是这个错误激起了鼠鼠的好奇心。

在这里插入图片描述

经过查找,本鼠发现,gets() 函数在C99中被弃用,在 C11 中被删除,此时需要用 fgets() 代替 gets() ,在好奇心的驱使下,本鼠简单学习了一下 fgets() 的使用方法。

fgets 的基本语法

fgets 的基本语法为

char *fgets( char *string, int n, FILE *stream );

参数:

string – 指向字符串(即 char 为元素的数组)

n – 输入字符串的长度

stream – 数据来源(一般为 stdin ,即标准输入流(键盘输入))

返回值:

成功时为 str,失败时为 NULL

使用示例

以倒序输出字符串为示例(注释中写到的注意事项会在下面讲解)

//倒序输出字符串
#include <stdio.h>
#include <string.h>

void reverse(char arr[], int length);

int main()
{
    char arr[20] = { 0 };
    //gets在C11被弃用
    //gets(arr);

    //注意fgets会把缓冲区中的\n也读取,并放在字符串中,而gtes()是将\n取出后丢弃
    //如果输入的长度恰好只剩一个位置的话,\n不会被存入字符串
    //最后一个位置一定是留给\0的
    fgets(arr, 18, stdin);
    int length = (int)strlen(arr);
    //strlen计算长度不包括\0

    reverse(arr, length);
    printf("%s", arr);
    return 0;
}

void reverse(char arr[], int length)
{
    char* pointer = arr + (length - 2);
    //考虑到\n占的位置
    //当\n不被存入字符串时,这里应该是-1
    int len = length;
    while (pointer >= arr)
    {
        char temp = *arr;
        *arr = *pointer;
        *pointer = temp;
        arr++;
        pointer--;
    }
}

fgets() 对输入的处理的特点

注意,以下结果均为自行测试得到,如有错误,敬请指正

测试代码

#include <stdio.h>

int main()
{
	char arr1[5] = { 0 };
	char arr2[5] = { 0 };
	fgets(arr1, 5, stdin);
	fgets(arr2, 5, stdin);
	
	printf("arr1 = %s\n", arr1);
	printf("arr2 = %s", arr2);
	return 0;
}
#include <stdio.h>

int main()
{
    char arr1[5] = { 0 };
    char arr2[5] = { 0 };
    gets(arr1);
    gets(arr2);

    printf("arr1 = %s\n", arr1);
    printf("arr2 = %s\n", arr2);
    return 0;
}

在使用 fgets() 时,当输入的字符串长度小于(规定最大长度 - 1)时,函数会将 \n 放在字符串的最后,并在 \n 后加上 \0 ,因此,打印该字符串时不需要输入换行符

在这里插入图片描述

而当输入字符串长达大于(规定最大长度 - 1)时,fgets() 会截取(规定最大长度 - 1)的字符,并在最后加上 \0 ,其余字符串包括 \n则会被留在缓冲区,这就导致了包括 \n 在内的字符会在下一次使用 fgets() 时被当作输入,使得该次 fgets() 被“跳过”

即 fgets() 保证 \0 的存在

在这里插入图片描述

缓冲区:可以看作输入设备和程序之间的一块区域,输入设备将字符输入至缓冲区,程序在需要时从缓冲区中取得字符


有时,缓冲区中的数据会对程序造成干扰,需要对缓冲区进行清理

//利用循环清理缓冲区
	int a = 0;
	while ((a = getchar()) != '\n')
	{
		;
	}

gets() 与 fgets() 的主要区别

  1. gets() 在输入时并不会考虑 \0 在字符串中的存在,因此当输入的字符串长度大于设定长度时,会因为 \0 不存在而导致越界访问,而 fgets() 一定会有 \0 的存在(输入abcdefghijklmnopqrst为示例),不会造成越界

在这里插入图片描述

在这里插入图片描述

  1. 即使输入的字符串长度超过设定长度,gets()也不会影响下一次的输入(但是会造成越界)

在这里插入图片描述

  1. fgets() 会将 \n 一并存入字符串,而 gets() 会将 \n 丢弃

在这里插入图片描述

总结

相较于get() ,fgets() 的使用更加复杂,但是更加安全,不存在越界访问等问题,同时,因为其可以设定输入长度,在某些特定情况下相较于gets()更加便利,将 fgets() 与清理缓冲区的代码搭配使用会是一个不错的选择。

STM32 FATFS文件系统按行读取SD卡数据 STM32 SD数据实现按行读取 阅读详情

相关推荐

Linux中fgets导致的进程阻塞解决方法

使用fork、pipe、dup2、execlp和select系统调用来实现更细粒度的popen控制; 使用select系统调用设置超时解决fgets引起的进程阻塞异常。

于归promax 1750

fgets函数及其用法,C语言fgets函数详解

虽然用 gets() 时有空格也可以直接输入,但是 gets() 有一个非常大的缺陷,即它不检查预留存储区是否能够容纳实际输入的数据,换句话说,如果输入的字符数目大于数组的长度,gets 无法检测到这个问题,就会发生内存越界,所以编程时建议使用 fgets()。 fgets() 的原型为: # include <stdio.h> char *fgets(char *s, int size, FILE *stream); fgets() 虽然比 gets() 安全,但安全是要付出代价...

digitalkee的博客 12万+

C语言中fgets函数的用法详解

在这个示例中,我们首先使用fopen函数打开了一个名为"example.txt"的文件,以只读模式(“r”)打开。然后,我们创建了一个大小为256的字符数组作为缓冲区,用于存储从文件中读取的字符串。请确保在使用fgets函数时,正确处理文件打开和关闭的操作,并且对于读取的字符串有足够的空间来存储。这个函数的作用是从指定的文件流(stream)中读取最多n-1个字符,并将其存储在字符数组str中。读取的字符包括换行符(‘\n’),并在末尾自动添加一个空字符(‘\0’),以表示字符串的结束。

TzData的博客 2352

7 - fgets()函数

fgets()函数学习

XDUryan的博客 1万+

ADS与MATLAB数据互通全指南:从Snp文件导入到TXT导出完整流程

本文详细介绍了在射频与微波工程中,实现ADS与MATLAB高效数据互通的完整流程。核心内容包括利用SPOutput控件、数据显示窗口及测量方程等多种方法,将ADS仿真数据(如S参数)导出为Touchstone或TXT格式,并导入MATLAB进行深度分析与可视化;同时指导如何将MATLAB处理后的数据回灌至ADS,用于模型验证与协同仿真,旨在构建自动化、无损的数据交换工作流,提升工程师的工作效率。

pluto的博客 393

Mooncake架构:基于KVCache解耦的LLM推理优化方案

在大语言模型推理中,KVCache是Transformer解码过程中用于缓存历史Key/Value向量的核心数据结构,它避免了序列重复计算,但会随上下文长度线性增长,成为显存占用的主要部分。其原理是在自回归生成时,将已计算过的注意力键值对存储下来,供后续Token生成时直接使用,从而提升计算效率。这项技术的核心价值在于,通过高效管理KVCache,可以显著降低长序列推理时的显存压力,提升GPU资源利用率。在实际应用场景中,尤其是在处理长上下文对话、高并发请求时,KVCache的管理策略直接决定了服务的吞吐量

weixin_35753431的博客 531

关于fgets()函数的使用方法

在读取字符串时,scanf()和转换说明符%s只能读取一个单词。gets()函数简单易用,它读取整行输入,直至遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符的末尾添加一个空字符使其成为一个C字符串。但是出现一个问题,gets()函数无法检测数组是否装得下输入行。于是,在2011年,C11标准委员会在标准中废除了gets()函数。 gets()函数的替代品 fgets() fgets()函数的第2个参数指明了读入字符的最大数量。如果该参数的值是n,那么fgets()将读入n-1个字符,或者读到遇到的第

qq_62096086的博客 1万+

从零开始掌握Python机器学习:七步教程 基础篇

前言 「开始」往往是最难的,尤其是当选择太多的时候,一个人往往很难下定决定做出选择。本教程的目的是帮助几乎没有 Python 机器学习背景的新手成长为知识渊博的实践者,而且这个过程中仅需要使用免费的材料和资源即可。 第一步:基本 Python 技能 如果我们打算利用 Python 来执行机器学习,那么对 Python 有一些基本的了解就是至关重要的。 首先,你需要安装 Python。因为我们后...

hcgx2018的博客 1613

fwrite函数,fread函数和fgets函数详解以及使用方法

fwrite函数,fread函数和fgets函数详解以及使用方法

qq_56673429的博客 4065

ArcGIS栅格拼接全攻略:从核心原理到色彩平衡与大数据处理

在GIS数据处理中,栅格拼接是一项基础且关键的操作,其本质是将多幅具有重叠区域的栅格图像无缝整合为一张完整地图。该技术涉及空间参考统一、像元对齐与色彩融合等核心原理,是构建连续地理空间数据的基石。其技术价值在于保障数据完整性、提升可视化效果,并为后续的空间分析提供可靠底图。在遥感影像处理、数字高程模型构建及地图制图等应用场景中,高质量的拼接成果至关重要。本文聚焦于ArcGIS平台,深入解析其栅格拼接工具,并针对常见的色彩不一致与大数据量处理难题,提供了基于**色彩平衡**和**金字塔**优化的实战解决方案,

weixin_33158887的博客 262

单片机:实现MPU6050的卡尔曼滤波算法(附完整源码)

单片机:实现MPU6050的卡尔曼滤波算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 798

C语言中关于fscanf()方法与fgets()方法的简单知识点总结

fscanf() int fscanf(FILE* stream, const char* format, [argument...]); fscanf()方法与scanf()方法类似。不同的是多了第一个参数,文件指针参数,后两个参数用法类似。其中要注意的是第三个参数处填写变量时,不要遗漏取地址符&。 要点 1. format str:如%d, %f, %c, %s等,分别表示读入一个整数,浮点数,字符,字符串。还可以加上控制,如%ld,表示读入一个长整型数,%20s表...

Charles_Clark的博客 8933

把 SAP ABAP BDC 跑得又快又稳:从 SHDB 录屏到可上线的批量上传程序(含 MM01 案例与源码)

SAP BDC批量数据迁移实践 摘要:本文介绍了SAP系统中BDC(Batch Data Communication)技术在数据迁移中的应用。文章首先对比了Session method和CALL TRANSACTION method两种实现方式的特点及适用场景,重点推荐使用Session method进行主数据批量处理。然后详细讲解了通过SHDB工具录制MM01事务创建物料主数据的完整流程,包括如何生成基础BDC代码。最后展示了将录制的脚本改造为可批量处理文件数据的实用程序,核心改动包括定义数据结构、读取文

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 322

C语言中 fputs() fgets() 的使用方法

  一、读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为: fgets(字符数组名,n,文件指针); 其中的n是一个正整数。表示从文件中读出的字符串不超过 n-1个字符。在读入的最后一个字符后加上串结束标志'/0'。例如:fgets(str,n,fp);的意义是从fp所指的文件中读出n-1个字符送入字符数组str中。  [例10.4]从e10...

weixin_33971130的博客 657

8.19华为OD机试真题 新系统 - 基站低能耗时段统计 (Java/Py/C/C++/Js/Go)

8.19华为OD机试真题 新系统 - 基站低能耗时段统计 (Java/Py/C/C++/Js/Go)

算法大师! 1146

基于STM32单片机设计的智能水温控制系统

本项目研究并实现了一种基于STM32单片机的智能水温控制系统。系统以STM32F103RCT6作为主控制器,通过DS18B20温度传感器实时采集水温数据,利用PID控制算法精确调节5V直流防水型70W加热棒的功率输出,确保水温恒定在设定范围内。此外,采用OLED显示屏显示当前水温和预设上限阀值,并集成ESP8266-WiFi模块与自研Android手机APP进行远程通信和控制。用户可通过本地按键或手机APP设置温度阀值,实现实时监控与智能化管理。整个系统设计旨在提高水资源利用效率,提升生活及工业用水环境的舒

8790

linux fputs函数,fputs() fgets() 的使用方法

fputs()fgets()的使用方法(2013-01-23 23:22:51)标签:linuxc语言it一、读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符数组中,函数调用的形式为:fgets(字符数组名,n,文件指针); 其中的n是一个正整数。表示从文件中读出的字符串不超过n-1个字符。在读入的最后一个字符后加上串结束标志'/0'。例如:fgets(str,n,fp);的...

weixin_39542043的博客 930

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

PHP 读取文件的三个方法fgets ,fgetcsv, fgetss

PHP 读取文件的三个方法fgets ,fgetcsv, fgetss

2469

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

fgets()函数和sscanf()函数的使用方法

fgets 百度百科:从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中。每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),假设文件里的该行,不足bufsize个字符,则读完该行就结束。如若该行(包含最后一个换行符)的字符数超过bufsize-1,则fgets仅仅返回一个不完整的行,可是,缓冲区总是以...

weixin_30446613的博客 222

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

fgets()重复读取最后一行的分析及解决方法

使用 fgets() 读取一个文本文件的时候,如果

yangguangqizhi的博客 8665

解决fgets标准输入读取超时的方法

从标准输入读入字符fgetc/getchar或fgets/gets字符串,都是堵塞等待输入的方法,无法在任务线程循环体中超时退出执行其他事务。解决的方法,是读取输入前先判断标准输入是否有数据,如果有再调用读取接口;/*****设置超时*******/

chengf223的博客 647

C语言字符串输入方法对比:scanf、fgets与getchar

在C语言编程中,字符串输入是基础但关键的操作,涉及缓冲区管理、安全性和效率等多方面考量。scanf、fgets和getchar是三种常用的输入函数,各自有不同的工作原理和适用场景。scanf适合简单格式输入但存在缓冲区溢出风险;fgets提供了更安全的字符串读取方式,能处理包含空格的输入;getchar则允许逐字符控制,适用于特殊输入处理。理解这些差异有助于开发者根据具体需求选择最佳方案,例如在学生信息系统中处理含空格的姓名,或在高安全性要求的密码输入场景。合理使用这些函数不仅能提升代码安全性,还能优化系统

weixin_30321449的博客 397

fgets和fputs的使用方法

#include int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "usage: %s filename1 filename2 \n",argv[0]); return -1; } FILE *fd1 = fopen (argv[1], "r")

red_rock的博客 873

gets()函数和fgets()函数的使用方法

gets()函数读取到\n(我们输入的回车)于是停止读取,但是它不会把\n包含到字符串里面去。然而,和它配合使用的puts函数,却在输出字符串的时候自动换行。fgets函数用来从文件中读入字符串。fgets函数的调用形式如下:fgets(str,n,fp);此处,fp是文件指针;str是存放在字符串的起始地址;n是一个int类型变量。函数的功能是从fp所指文件中读入n-1个字符放入str为起始地址的空间内;

醉饮半壶酒的博客 4604

有关scanf()和fgets()函数的使用方法

原来在printf语句中,最后一行有一个\n,\n作为scanf()的输入了,这时就会出现输入错误,导致了程序的无限循环。为了避免scanf()输入会容易遇到一些错误,在程序中尽量使用fgets()函数做输入函数,fgets()函数时读取一行数据。2.scanf()由于是回车符结束(或者空格符结束),所以在缓存区里会有回车符,在循环使用scanf()函数做输入时,会出现程序进入死循环。代码中是只有输入整数时,程序才执行打印a的值,代码输入错误时,打印b的值,然后继续输入,当输入时,1 23 guah。

GWL9090的博客 486
上一篇: 常用调试方法
下一篇: C语言对类型的转换
flashier
博客等级 码龄3年 381粉丝 79原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值