fgets的使用方法详解

2024-02-16 22:28
文章标签 使用 方法 详解 fgets

本文主要是介绍fgets的使用方法详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

fgets的使用

文章目录

  • fgets的使用
    • 前言(吹水,不看也罢)
    • fgets 的基本语法
    • 使用示例
    • fgets() 对输入的处理的特点
      • gets() 与 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计算长度不包括\0reverse(arr, length);printf("%s", arr);return 0;
}void reverse(char arr[], int length)
{char* pointer = arr + (length - 2);//考虑到\n占的位置//当\n不被存入字符串时,这里应该是-1int 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() 与清理缓冲区的代码搭配使用会是一个不错的选择。

这篇关于fgets的使用方法详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715876

相关文章

web网络安全之跨站脚本攻击(XSS)详解

《web网络安全之跨站脚本攻击(XSS)详解》:本文主要介绍web网络安全之跨站脚本攻击(XSS)的相关资料,跨站脚本攻击XSS是一种常见的Web安全漏洞,攻击者通过注入恶意脚本诱使用户执行,可能... 目录前言XSS 的类型1. 存储型 XSS(Stored XSS)示例:危害:2. 反射型 XSS(Re

前端bug调试的方法技巧及常见错误

《前端bug调试的方法技巧及常见错误》:本文主要介绍编程中常见的报错和Bug,以及调试的重要性,调试的基本流程是通过缩小范围来定位问题,并给出了推测法、删除代码法、console调试和debugg... 目录调试基本流程调试方法排查bug的两大技巧如何看控制台报错前端常见错误取值调用报错资源引入错误解析错误

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

Go 1.23中Timer无buffer的实现方式详解

《Go1.23中Timer无buffer的实现方式详解》在Go1.23中,Timer的实现通常是通过time包提供的time.Timer类型来实现的,本文主要介绍了Go1.23中Timer无buff... 目录Timer 的基本实现无缓冲区的实现自定义无缓冲 Timer 实现更复杂的 Timer 实现总结在

如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件

《如何使用Docker部署FTP和Nginx并通过HTTP访问FTP里的文件》本文介绍了如何使用Docker部署FTP服务器和Nginx,并通过HTTP访问FTP中的文件,通过将FTP数据目录挂载到N... 目录docker部署FTP和Nginx并通过HTTP访问FTP里的文件1. 部署 FTP 服务器 (

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

MySQL 日期时间格式化函数 DATE_FORMAT() 的使用示例详解

《MySQL日期时间格式化函数DATE_FORMAT()的使用示例详解》`DATE_FORMAT()`是MySQL中用于格式化日期时间的函数,本文详细介绍了其语法、格式化字符串的含义以及常见日期... 目录一、DATE_FORMAT()语法二、格式化字符串详解三、常见日期时间格式组合四、业务场景五、总结一、

Qt实现发送HTTP请求的示例详解

《Qt实现发送HTTP请求的示例详解》这篇文章主要为大家详细介绍了如何通过Qt实现发送HTTP请求,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、添加network模块2、包含改头文件3、创建网络访问管理器4、创建接口5、创建网络请求对象6、创建一个回复对

Python中配置文件的全面解析与使用

《Python中配置文件的全面解析与使用》在Python开发中,配置文件扮演着举足轻重的角色,它们允许开发者在不修改代码的情况下调整应用程序的行为,下面我们就来看看常见Python配置文件格式的使用吧... 目录一、INI配置文件二、YAML配置文件三、jsON配置文件四、TOML配置文件五、XML配置文件