【C语言进阶】一次解决字符串输入问题——为什么输入这么容易奔溃?

news2024/9/30 9:26:21

文章一览

  • 写在前面
  • 一、scanf、getchar与gets函数的爱恨情仇
    • 1.1 scanf函数
      • 1.1.1 %c输入单个字符
      • 2. %s 输入字符串
      • 1.1.3 %d输入数字
    • 1.2 getchar函数
    • 1.3 gets函数
  • 二、不同输入情况下的使用
  • 三、回顾C语言的输入函数
  • 总结

写在前面

 在之前的文章中,笔者详细介绍了scanf函数的使用(scanf函数从入门到精通),但是在后续的使用中发现,还是有一些细节的地方没有很好的处理,容易导致系统奔溃。
在这里插入图片描述

 那么接下来的部分就让大家跟随笔者的思路一起探讨一下这部分的处理。(以下观点仅为笔者观点,如有不当之处欢迎大家指出。)

一、scanf、getchar与gets函数的爱恨情仇

 这三个函数都是C语言中的输入流函数,但是各自的使用有所不同。从名字上来看,scanf函数是格式化输入函数,所以理论上来说它可以输入各种数据;getchar函数是字符输入函数,它只能以字符形式输入且每次输入一个;gets函数是一个字符串输入函数,它每一次可以将一行字符输入到某地址。

1.1 scanf函数

scanf函数在遇到“空白字符”时会结束掉,并且该空白字符依然在缓冲区中。
  这里的空白字符指:空格、换行符(\n)、制表符(\t)等。

1.1.1 %c输入单个字符

使用%c格式化输入时,与getchar作用一致,也可以接收到'\n'这种空白字符。
在这里插入图片描述

2. %s 输入字符串

在这里插入图片描述
可以看到在使用%s格式化输入时,scanf函数会输入'\n'之前的字符,并且在输入完成后默认为字符串末尾加上一个'\0',这时末尾的'\n'依然留在缓冲区。
在这里插入图片描述
当标准输入有**“空白字符”**时scanf函数会结束掉,把之前的字符串放到字符串中,同样在末尾加上一个'\0',后面的空格' ' 也依然在缓冲区中。

1.1.3 %d输入数字

正常输入时,同样的情况,缓冲区中依然会留着'\n'
在这里插入图片描述
输入完两个数字之后,空格再加回车,后面的空格依然留在缓冲区中。
在这里插入图片描述
输入一堆空格然后再输入数字,对数字的输入是没有任何影响的,可以参考前言中的文章,%d的格式输入符会让%d 去寻找到数字才开始输入。
在这里插入图片描述
在scanf函数中接收最后一个数字(%d)后打上一个空格(也就是去接收一个空格)时,在输入第二个数字之后不管输入多少个空格都不会留到缓冲区,并且连\n都会被处理掉,不留在缓冲区。
在这里插入图片描述

1.2 getchar函数

getchar函数的使用比较简单,每次都会吸收一个字符,不管任何字符都可以被吸收。
这里的任何字符包括了空格等字符,没有被接收的字符依然在缓冲区,也包括'\n'
在这里插入图片描述

1.3 gets函数

gets函数的使用也比较简单,它只在遇到\n才会停止,也就是说只能读取一行。
下面由于VS不支持gets了,对gets进行了安全保护改造为gets_s函数,但是原理是一样的。
在这里插入图片描述
如图可见,gets函数在遇到换行符(\n)时停止,往写入的字符串末尾加上'\0'(这里类似scanf函数的%s输入),接下来会处理掉末尾的'\n'(这里与scanf函数不同)
在这里插入图片描述
在遇到空格等任何字符都会正常接收。
在这里插入图片描述
当在标准输入流中手动输入'\n'时,编译会认为你只是想输入\n两个字符,而不是'\n', 编译器会自动改造\\\也就是加入了一个转义字符。

二、不同输入情况下的使用

那么有了理论我们做几个题来巩固一下,实现下列输入:

  1. 输入三个数字
  2. 输入两个数字之后,下一行输入一个字符(数字之后无空格等符号)
  3. 输入两个数字之后,下一行输入一个字符(数字之后可能带有或不带空格字符)
  4. 第一行输入一个字符串(字符串中可能包含空格),第二行输入一个数字(考虑分别使用gets和scanf函数
  5. 第一行输入一个字符串(字符串中可能包含空格),第二行再输入一个字符串
  6. 第一行输入一个字符串(字符串中可能包含空格),第二行输入一个字符

做出来之后可以发到评论区晒晒哟,看看你自己会做了没有!!!

三、回顾C语言的输入函数

scanf、getchar、gets函数的对比:

函数输入格式是否可以输入空格字符是否自动处理’\n’是否自动加入’\0’
scanf(“%c”)字符------
getchar()字符------
scanf(“%s”)字符串
gets()字符串
scanf(“%d”)十进制整数------------

总结

 在使用这些函数时,需要关注错误处理。例如,scanf函数在读取失败时会返回EOF,而getchar也会在遇到文件末尾或读取错误时返回EOF。正确处理这些错误情况可以提高程序的健壮性。

  • 安全性:gets函数因其缓冲区溢出风险而被弃用,这强调了在处理输入数据时考虑安全性的重要性。使用fgets等更安全的函数可以减少潜在的安全漏洞。
  • 跨平台兼容性
    跨平台编程:尽管这些函数的行为在不同操作系统上可能略有差异(特别是在处理换行符时),但它们通常都是跨平台兼容的,使得编写能够在多种操作系统上运行的程序成为可能。
    在这里插入图片描述

scanf、gets(及其更安全的替代fgets)和getchar函数在C语言中的应用广泛且重要,它们不仅用于读取用户输入和处理数据,还涉及到用户交互、文本处理、错误处理和安全性等多个方面。在编写C语言程序时,合理利用这些函数可以大大提高程序的灵活性和实用性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Springboot+Vue的课程教学平台的设计与实现系统(含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

Arm Linux 交叉编译openssl 1.1.1

一、openssl 源码下载 OpenSSL的官方网站或源代码仓库下载最新或指定版本的OpenSSL源代码。 官网地址: https://openssl-library.org/source/index.html 旧版本下载: https://openssl-library.org/source/old/index.html 这里以 1.1.1 为例 国内git…

网线最短不能短于1米?

大家都知道网线最长不能长于100米,但你有没有听说过“网线最短不能短于1米”这个说法呢?也有的朋友说不能低于0.6米。 有的网友说“‌‌网线最短1米的说法是真的。‌ 短于1米的网线电阻几乎为零,设备可能无法识别,因此在实际应用中…

Android 安卓内存安全漏洞数量大幅下降的原因

谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码,尽管旧代码(用 C/C 编写)没有被重写,但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量(来源:谷歌&#xff09…

【前端开发入门】html快速入门

目录 引言html基础模板内容html文档流html 标签块级元素行内元素功能性元素标签嵌套 html编码习惯总结 引言 本系列教程旨在帮助一些零基础的玩家快速上手前端开发。基于我自学的经验会删减部分使用频率不高的内容,并不代表这部分内容不重要,只是对于初学…

一站式大语言模型API调用:快速上手教程

智匠MindCraft是一个强大的AI工具及开发平台,支持多种大语言模型和多模态AI模型。本文将详细介绍如何通过API调用智匠MindCraft中的大语言模型,帮助开发者快速上手。 注册与登录 访问智匠MindCraft官网,注册并登录账号。 进入开发者平台&…

86、Python之鸭子类型:即便行为大于类型,还是要聊一下类型转换

引言 我们的最近几篇文章一直在聊的是鸭子类型,以及支撑鸭子类型相关的魔术方法的内容。其实,鸭子类型的本质在于“行为大于类型”。但是,并不是说类型不重要,只是在特定领域中,行为本身高于类型形式,或者…

爬虫及数据可视化——运用Hadoop和MongoDB数据进行分析

作品详情  运用Hadoop和MongoDB对得分能力数据进行分析;  运用python进行机器学习的模型调理,利用Pytorch框架对爬取的评论进行情感分析预测;  利用python和MySQL对网站的数据进行爬取、数据清洗及可视化。

Chainlit集成LlamaIndex实现知识库高级检索(组合对象检索)

检索原理 对象组合索引的原理 是利用IndexNode索引节点,将两个不同类型的检索器作为节点对象,使用 SummaryIndex (它可以用来构建一个包含多个索引节点的索引结构。这种索引通常用于从多个不同的数据源或索引方法中汇总信息,并能…

零工市场小程序如何提高找兼职的效率?

越来越多的人们会选择成为自由职业者,或者在空暇时兼职来获取酬劳,那么传统的找兼职方式,如:中介公司、招聘广告等。 如今大家的生活都已经进入了“快节奏”,零工市场小程序针对这样的问题而提出了解决方案&#xff0…

python Scrapy 框架 demo

文章目录 前言python Scrapy 框架 demo1. 安装2. 百度热搜爬取demo2.1. 初始化项目2.2. 修改 items.pyitems.py2.3. 创建 spiders/baidu_spider.py2.4. 修改 pipelines.py2.5. 修改 settings.py 3. settings.py 相关配置说明4. 启动爬虫测试 前言 如果您觉得有用的话&#xff0…

python+requests接口测试

pythonrequest 一、调用的方法 requests是一个第三方库 (1) a、下载地方库pip install requests b、pycaharm中下载 (2)导入requests库 (3)requests中的三种调用方法 第一种: requests.…

算法训练营打卡Day18

目录 二叉搜索树的最小绝对差二叉搜索树中的众数二叉树的最近公共祖先额外练手题目 题目1、二叉搜索树的最小绝对差 力扣题目链接(opens new window) 给你一棵所有节点为非负值的二叉搜索树,请你计算树中任意两节点的差的绝对值的最小值。 示例: 思…

时间复杂度及空间复杂度(简略)

目录 时间复杂度空间复杂度 时间复杂度 计算时间复杂度时,我们只需计算大致执行次数,再用大O的渐进表示法就可以了 常见的复杂度为O(N),O(1),O(N^2)的几个情况这里就不提了,下面是几个相对来说需要分析的算法 算法1: // 计算str…

【Python报错已解决】TypeError: ‘int‘ object is not subscriptable

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

如何在实际开发中深入使用 yalantinglibs 编译期反射库

yaLanTingLibs 是阿里云开源的现代 C 基础工具库的集合,包括序列化、http、rpc、协程、编译期反射、metric 和日志等库,可以帮助 C 开发者快速构建高性能的 C 应用。2024 云栖大会操作系统技术 Workshop 上,阿里云智能集团高级技术专家、pure…

快手:数据库升级实践,实现PB级数据的高效管理|OceanBase案例

本文作者:胡玉龙,快手技术专家 快手在较初期采用了OceanBase 3.1版本成功替换了多个核心业务、数百套的MySQL集群。至2023年,快手的数据量已突破800TB大关,其中最大集群的数据量更是达到了数百TB级别。为此,快手将数据…

Docker安装consul + go使用consul + consul知识

1. 什么是服务注册和发现 假如这个产品已经在线上运行,有一天运营想搞一场促销活动,那么我们相对应的【用户服务】可能就要新开启三个微服务实例来支撑这场促销活动。而与此同时,作为苦逼程序员的你就只有手动去 API gateway 中添加新增的这…

基于AI的智能化渗透测试技术研究

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

问题:vscode 打印中文时终端输出乱码

文章目录 问题分析解决 问题 在 vscode 编辑器中的终端运行出来的中文是乱码 分析 乱码原因:因windows中文版系统cmd编码默认为GBK,而vscode默认新建文件的编码为UTF-8所以会出现中文乱码情况 解决 终端下输入 chcp 查看当前的cmd编码设置。如图&…