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() 与清理缓冲区的代码搭配使用会是一个不错的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/258923.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElementUI Form:Cascader 级联选择器

ElementUI安装与使用指南 Cascader 级联选择器 点击下载learnelementuispringboot项目源码 效果图 el-cascader.vue&#xff08;Cascader 级联选择器&#xff09;页面效果图 项目里el-cascader.vue代码 <script> let id 0; export default {name: el_cascader,dat…

读书笔记之《我的大脑好厉害》:脑科学启蒙

《我的大脑好厉害》的作者是赵思家&#xff0c;于 2022年出版。 赵思家是牛津大学神经科学博士后&#xff0c;科普作者&#xff0c;知乎神经科学领域大V&#xff0c;46万关注&#xff0c;擅长为充满好奇的读者提供新鲜、有趣又不失严谨的神经科学知识。赵思家2013年毕业于伦敦大…

【Python--Web应用框架大比较】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; Django Django太重了&#xff0c;除了web框架&#xff0c;自带ORM和模板引擎&#xff0c;灵活和自由度不…

SpringBoot实现OneDrive文件上传

SpringBoot实现OneDrive文件上传 源码 OneDriveUpload: SpringBoot实现OneDrive文件上传 获取accessToken步骤 参考文档&#xff1a;针对 OneDrive API 的 Microsoft 帐户授权 - OneDrive dev center | Microsoft Learn 1.访问Azure创建应用Microsoft Azure&#xff0c;使…

阿里云服务器配置选择方法和经验(CPU+内存+宽带)

阿里云服务器配置怎么选择&#xff1f;根据实际使用场景选择&#xff0c;个人搭建网站可选2核2G配置&#xff0c;访问量大的话可以选择2核4G配置&#xff0c;企业部署Java、Python等开发环境可以选择2核8G配置&#xff0c;企业数据库、Web应用或APP可以选择4核8G配置或4核16G配…

计算机网络——15套接字编程

套接字编程 Socket编程 Socket编程&#xff1a;应用进程使用传输层提供的服务才能够交换报文&#xff0c;实现应用协议&#xff0c;实现应用 TCP/IP&#xff1a;应用进程使用Socket API访问传输服务 地点&#xff1a;界面上的SAP 方式&#xff1a;Socket API 目标&#xff1…

将其它输入法的词库转换为微软拼音输入法的自学习词库

上班第一天&#xff0c;我删除了搜狗输入法 曾几何时&#xff0c;搜狗拼音输入法&#xff0c;以丰富的词库&#xff0c;实用的设置成为我电脑端主要的中文输入法。但新年上班的第一天&#xff0c;我彻底删除了它&#xff0c;回归到微软拼音输入法。因为&#xff0c;最近&#…

java面试微服务篇

目录 目录 SpringCloud Spring Cloud 的5大组件 服务注册 Eureka Nacos Eureka和Nacos的对比 负载均衡 负载均衡流程 Ribbon负载均衡策略 自定义负载均衡策略 熔断、降级 服务雪崩 服务降级 服务熔断 服务监控 为什么需要监控 服务监控的组件 skywalking 业务…

CSS画一个三角形(面试必问)

目录 一、前言二、实现过程三、原理分析参考文献 一、前言 在前端开发的时候&#xff0c;我们有时候会需要用到一个三角形的形状&#xff0c;比如地址选择或者播放器里面播放按钮 通常情况下&#xff0c;我们会使用图片或者svg去完成三角形效果图&#xff0c;但如果单纯使用cs…

七、ActiveMQ的传输协议

ActiveMQ的传输协议 一、是什么二、协议1.TCP(默认)2.NIO3.AMQP4.STOMP5.SSL6.MQTT7 WS 三、NIO配置案例1.修改activemq.xml2.重启3.生产者/消费者4.性能提升4.1 配置4.2 生产者/消费者 一、是什么 官网地址&#xff1a;http://activemq.apache.org/configuring-version-5-tra…

[嵌入式系统-27]:RT-Thread -14- 操作系统配置:rtconfig.h文件与menuconfig命令

目录 一、rtconfig.h 1.1 概述 1.2 软硬件资源配置 1.3 功能模块选择 1.4 内核配置详解 1.5 调度器配置 1.6 硬件设备驱动配置 1.7 网络配置 1.8 调试配置 二、menuconfig 2.1 概述 2.2 主要功能 三、RT Thread配置 VS Linux配置 一、rtconfig.h 1.1 概述 rtco…

电商API接口|大数据关键技术之数据采集发展趋势

在大数据和人工智能时代&#xff0c;数据之于人工智能的重要性不言而喻。今天&#xff0c;让我们一起聊聊数据采集相关的发展趋势。 本文从电商API接口数据采集场景、数据采集系统、数据采集技术方面阐述数据采集的发展趋势。 01 数据采集场景的发展趋势 作为大数据和人工智…

前端工程化面试题 | 13.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

17.Qt 单选框相关操作

目录 前言&#xff1a; 技能&#xff1a; 内容&#xff1a; 1. 布置界面 2.管理 3.槽函数 参考&#xff1a; 前言&#xff1a; 组合选择只能选择一个的单选框实现&#xff0c;以及管理组合单选框 技能&#xff1a; <QRadioButton> <QButtonGroup> 内容&…

GPT SOVITS项目 一分钟克隆 (文字输出)

步骤流程&#xff1a;&#xff08;首先使用UVR 提取人声文件&#xff0c;然后按下面步骤进行&#xff09; 注意这里提交的音频是参考的音频

第三百四十九回

文章目录 1. 概念介绍2. 原理与方法2.1 知识对比2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"加密包crypto"相关的内容&#xff0c;本章回中将介绍characters包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 在项目中会遇到获取字…

C高级D5作业

1.#!/bin/bash read -p "请输入一个字符>>" -n 1 c echo case $c in [[:lower:]]) echo "小写" ;; [[:upper:]]) echo "大写" ;; [1-9]) echo "数字" ;; …

使用MinIO S3存储桶备份Weaviate

Weaviate 是一个开创性的开源向量数据库&#xff0c;旨在通过利用机器学习模型来增强语义搜索。与依赖关键字匹配的传统搜索引擎不同&#xff0c;Weaviate 采用语义相似性原则。这种创新方法将各种形式的数据&#xff08;文本、图像等&#xff09;转换为矢量表示形式&#xff0…

OpenGL学习——14.投光物_点光源

前情提要&#xff1a;本文代码源自Github上的学习文档“LearnOpenGL”&#xff0c;我仅在源码的基础上加上中文注释。本文章不以该学习文档做任何商业盈利活动&#xff0c;一切著作权归原作者所有&#xff0c;本文仅供学习交流&#xff0c;如有侵权&#xff0c;请联系我删除。L…

JDK新特性

JDK新特性 函数式接口和Lambda 表达式Stream流操作新日期API操作其他新特性 Lambda 是一个匿名函数&#xff0c;我们可以把 Lambda表达式理解为是一段可以传递的代码&#xff08;将代码 像数据一样进行传递&#xff09;。可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码…