爱上C语言:scanf、gets以及getchar输入字符串你真的懂了吗

news2024/9/24 18:38:46

🚀 作者:阿辉不一般
🚀 你说呢:不服输的你,他们拿什么赢
🚀 专栏:爱上C语言
🚀作图工具:draw.io(免费开源的作图网站)
请添加图片描述

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!!

文章目录

  • 🚀前言
  • 🚀输入缓冲区
  • 🚀scanf()函数
  • 🚀gets()函数
  • 🚀getchar()函数
    • ✈️清空输入缓冲区

🚀前言

大家好啊😉!今天阿辉将为大家介绍C语言中scanf、gets以及getchar关于字符串的输入,关注阿辉不迷路哦 😘 ,内容干货满满😋,接下来就跟着阿辉一起学习吧👊

🚀输入缓冲区

输入缓冲区是计算机系统中用于存储输入数据的一种缓冲区
怎么理解他呢,比如我们C语言中的scanf以及今天阿辉要介绍的函数,他们并非直接读取我们在键盘上敲的数据,而是我们敲的数据先存在缓冲区内,然后scanf从缓冲区里面读取的

请添加图片描述
注意:
上面的图只是简单的描述,输入缓冲区就像你的饭卡你往里面充钱,一次可能充100块,但是scanf这顿饭可能就只读12块
阿辉今天要讲的就是scanf、gets、getchar以及fgets在缓冲区中是如何读取的
输入缓冲区的数据一旦被读取就不再输入缓冲区了

🚀scanf()函数

scanf()相信大家都不陌生,他就是通过占位符从标准输入流中格式化的读取数据然后把数据存储在参数所指向的位置
1.标准输入流默认是键盘输入
2.参数就是地址,例如&a这样
我们来看一个🌰栗子

#include<stdio.h>

int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	printf("a = %d b = %d\n", a, b);
	scanf("%d%d", &a, &b);
	printf("a = %d b = %d\n", a, b);
	return 0;
}

在这里插入图片描述
注意:只要scanf不是使用%c读取数据时,数据前面的空白字符(空格、制表符以及换行)都会被忽略
好吧以上都不是重点😆,重点是对于字符串的读取
上星期一道牛客OJ题给阿辉整的汗流浃背(点击可跳转)
题目:

输入描述:
输入一个字符串,可以有空格

输出描述:
输出逆序的字符串

示例1
输入
I am a student
输出
tneduts a ma I

关于这道题的代码

#include <stdio.h>
#include <string.h>

void reverse(char *p, int sz) {
    int i = 0;
    int j = sz - 1;
    for (i = 0, j = sz - 1; i < sz / 2; i++, j--) {
        char tmp = *(p + i);
        *(p + i) = *(p + j);
        *(p + j) = tmp;
    }
}

int main() 
{
    char arr[10000] = {0};
    int i = 0;
    scanf("%[^\n]%*c",arr);
    int sz = strlen(arr);
    reverse(arr, sz);
    printf("%s", arr);
    return 0;
}

孤陋寡闻的阿辉只会用scanf%s读,而%s遇到空格换行制表符就会停止读取,用%c读,换行\n都给我读来了我靠真的汗流浃背了,阿辉急忙翻题解,我丢这题解真是让人两眼放光😍,gets还有scanf的高级用法
scanf读字符串的神仙用法:

  • scanf可以通过字符集的方式读取字符scanf("%[a-z]",str)a-z指的是只读取a到z之间的小写字母,遇到非范围内的字符停止读取,当然你也可以用[A-Z]只读大写字母,范围自定义
  • scanf("%[ ^\n ]",str)^\n指的是只读取非\n的字符包括制表符和空格,遇到换行停止读取,当然你也可以^\t,都是是自定义的
  • scanf("%*c",str)*指的是对于一个字符类型的数据只读取但不存储给任何变量,就是把这个数据从输入缓冲区去掉这一个操作,也可以%*d,也是自定义的
    🌰栗子
int main()
{
	char str1[10] = { 0 };
	char str2[10] = { 0 };
	scanf("%[a-z]", str1);
	scanf("%[^\n]", str2);
	printf("%s\n", str1);
	printf("%s", str2);
	return 0;
}
输入:
abcd1换行
输出:
abcd     --第一行
1		 --第二行

因为第一个scanf只读取a-z之间的数据,读到1停止读取,而1后面还有一个换行,1和换行都还在输入缓冲区内,因为第二个scanf读到换行就会停止读取,因为输入缓冲区有换行了,你连键盘输入的机会都没有了,这里\n还留在输入缓冲区
这里我们对输入缓冲区的理解应该更加清晰了,scanf从缓冲区读取数据,输入缓冲区有适合的数据就不需要你输入了,就像你饭卡有钱就不用充钱了

如果我们这么写

int main()
{
	char str1[10] = { 0 };
	char str2[10] = { 0 };
	scanf("%[a-z]%*d%*c", str1);
	scanf("%[^\n]%*c", str2);
	printf("%s\n", str1);
	printf("%s", str2);
	return 0;
}
输入:
abcd1换行
ab123换行
输出;
abcd	--第一行
ab123	--第二行

这里第一个scanf里面的%*d%*c1和换行\n给读取了但并未赋给任何变量,我的理解就是把输入缓冲区一个有符号数和一个字符给删掉,然后到第二个scanf的时候输入缓冲区就没数据了得我们自己输入

🚀gets()函数

gets这个函数并不会检查输入的长度,可能导致缓冲区溢出,并不建议大家使用,可能出bug,不过gets这个函数还是很猛的。
用法:

char *gets(char *str);
str指向字符数组的指针
返回值,读取成功为str,读取错误为EOF

gets(str)只能读取字符包括空格和制表符直到遇到换行符或者文件结束符停止读取然后将\n从输入缓冲区删除,相当于scanf("%[ ^\n ]%*c",str)

🚀getchar()函数

getchar()从键盘获取一个字符,返回值也是这个字符,无参数,直到用户按下回车键或输入的字符达到了缓冲区的最大长度,停止读取,一次只读取一个字符包括空格、换行和制表符,相当于scanf("%c",c)

✈️清空输入缓冲区

利用getchar()我们可以写一个清空输入缓冲区的函数

void clearbuffer(void)
{
	while (getchar() != '\n')
	{
		;
	}
}

int main()
{
	char str1[10];
	char str2[10];
	scanf("%s", str1);
	clearbuffer();
	scanf("%s", str2);
	printf("str1 = %s\n", str1);
	printf("str2 = %s\n", str2);

	return 0;
}

输入输出
在这里插入图片描述
1234\n都被clearbuffer这个函数读取了,从输入缓冲区清除了

这里while判断的条件是getchar != ‘\n’getchar读取到哪个字符,它的返回值就是哪个字符,所以,这里我们这样来清空缓冲区,是连带\n一起清理掉的(当getchar()吸收了’\n’,则getchar() == ‘\n’ ,不满足条件就退出while循环了)


到这里,阿辉今天对于C语言中的scanf、gets以及getchar分享就结束了,希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹
请添加图片描述

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

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

相关文章

计算机组成原理2

1.浮点数 2.IEEE 754 3.存储器的性能指标 4.存储器的层次化结构 主存类似手机运行内存8g &#xff0c;辅存类似手机内存128g.... 辅存必须先通过主存才能被cpu接收&#xff0c;就例如微信打开那个月亮小人界面两三秒就是主存在读取辅存的程序然后被cpu接收运行。 5.主存储…

EMG肌肉电信号处理合集(三)

本文主要展示常见的肌电信号预处理的实现&#xff0c;开发环境为matlab。 目录 1 肌电信号低通&#xff0c;高通&#xff0c;带通滤波 2 去除DC 0阶偏置&#xff0c;1阶偏置 3 全波整流 4 信号降采样 5 linear envolope / butterworth 低通滤波器 1 肌电信号低通&#xf…

(一)C语言之入门:使用Visual Studio Community 2022运行hello world

使用Visual Studio Community 2022运行c语言的hello world 一、下载安装Visual Studio Community 2022 与 新建项目二、编写c helloworld三、编译、链接、运行 c helloworld1. 问题记录&#xff1a;无法打开源文件"stdio.h"2. 问题记录&#xff1a;调试和执行按钮是灰…

【LeetCode】挑战100天 Day13(热题+面试经典150题)

【LeetCode】挑战100天 Day13&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-152.1 题目2.2 题解 三、面试经典 150 题-153.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

Node使用Nvm安装双版本切换(node两个版本同时用怎么办?不同的项目Node版本要求不一样怎么办?)

先把node.js卸载 开始—>添加删除程序—>node npm -v node -v //检查是否还存在&#xff0c;卸载成功就行了NVM下载 github下载 百度网盘下载 打开安装包以管理员身份安装&#xff0c;要是记得这个路径并且必须全是英文 使用nvm安装两个使用的node版本 cmd以管理员…

手撕A*算法(详解A*算法)

A*算法原理 全局路径规划算法&#xff0c;根据给定的起点和终点在全局地图上进行总体路径规划。 导航中使用A*算法计算出机器人到目标位置的最优路线&#xff0c;一般作为规划的参考路线 // 定义地图上的点 struct Point {int x,y; // 栅格行列Point(int x, int y):x(x),y(y){…

【C++】拷贝构造函数,析构函数详解!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

国家超级计算济南中心低代码平台应用实践

摘要&#xff1a;文章主要介绍了济南超算使用低代码平台明道云解决了一系列业务问题&#xff0c;包括资产管理、人员与机构管理、流程制度管理等。通过明道云平台&#xff0c;济南超算成功地将不同部门的业务信息进行整合&#xff0c;提高了工作效率和管理水平。文章还强调了明…

外部网关协议_边界网关协议BGP

一.边界网关协议BGP的基本概念 边界网关协议(Border Gateway Protocol&#xff0c;BGP&#xff09;属于外部网关协议EGP这个类别&#xff0c;用于自治系统AS之间的路由选择协议。由于在不同AS内度量路由的“代价”(距离、带宽、费用等&#xff09;可能不同&#xff0c;因此对于…

批量创建表空间数据文件(DM8:达梦数据库)

DM8:达梦数据库 - - 批量创建表空间数据文件 环境介绍1 批量创建表空间SQL2 达梦数据库学习使用列表 环境介绍 在某些场景(分区表子表)需要批量创建表空间,给不同的表使用,以下代码是批量创建表空间的SQL语句; 1 批量创建表空间SQL --创建 24个数据表空间,每个表空间有3个数…

LeetCode.283移动零(双指针)

LeetCode.283移动零 1.问题描述2.解题思路3.代码 1.问题描述 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1…

在一个页面里向两张表里插入内容时,有一些复杂的BUG简单化

向两张表里插入内容时&#xff0c;有一些复杂的BUG简单化 当在第一张表里的页面操作&#xff0c;在第一张表查询结果的页面进行编辑&#xff0c;在编辑的时候需要对第二张表里和第一张表都保存内容&#xff0c;而且插入之后两张表的id关联着&#xff0c;这个时候这张表的id就不…

【LeetCode】挑战100天 Day12(热题+面试经典150题)

【LeetCode】挑战100天 Day12&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-142.1 题目2.2 题解 三、面试经典 150 题-143.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

2023年度全国国土变更调查工作相关技术文档、质检软件

1.资料清单&#xff1a; (1)01技术文件 2023年度国土变更调查数据库建设技术要求.pdf 2023年度全国国土变更调查实施方案.doc 附件1.国土调查数据库更新数据规范&#xff08;2023年度&#xff09;.pdf 附件2.国土调查数据库更新变更规则&#xff08;2023年度&#xff09;.pdf…

unity3d人物由静止到跑,出现人物漂移一段距离后再跑

减少动画切换过程中第一个动画的时间&#xff0c;交叉部分适当调小&#xff0c;动作切换就顺畅了

大模型生态新篇章:以AI Agent为引,助企业创新应用落地

文 | 智能相对论 作者 | 沈浪 以聊天机器人、虚拟助手、智能客服等为代表的对话式人工智能 (Conversational AI Agents ) 在具体服务场景中的应用已经十分普遍。今年以来&#xff0c;随着大模型技术的爆发与加持&#xff0c;对话式AI被市场赋予了更高的期望。 “所有行业都值…

C语言——指针(一)

&#x1f4dd;前言 这篇文章主要带大家初步认识一下指针&#xff0c;供大家理解参考。 主要归纳与讲解&#xff1a; 1&#xff0c;指针与指针变量 2&#xff0c;指针的基本使用&#xff08;如何定义&#xff0c;初始化&#xff0c;引用&#xff09; &#x1f3ac;个人简介&…

线性回归中的函数求导

在线性回归中&#xff0c;函数求导是一个重要的数学工具&#xff0c;用于计算损失函数关于模型参数的导数。通过求导&#xff0c;我们可以找到最优的参数值&#xff0c;以实现更好的线性回归拟合。 本文将介绍线性回归的基本原理&#xff0c;以及如何通过函数求导来优化线性回…

【JavaEE】Spring小练习——存储和获取对象

一、题目&#xff1a; 在 Spring 项目中&#xff0c;通过 main 方法获取到 Controller 类&#xff0c;调用 Controller 里面通过注入的方式调用Service 类&#xff0c;Service 再通过注入的方式获取到 Repository 类&#xff0c;Repository 类里面有一个方法构建⼀个 User 对象…

掌动智能带您深入了解业务连续性演练

业务连续性演练是一种有目的的模拟活动&#xff0c;旨在测试和评估组织业务连续性计划的有效性。这涉及到模拟各种可能的业务中断情况&#xff0c;以便团队可以在真实事件发生时做出迅速、协调的响应。 一、业务连续性演练设计原则 全面性&#xff1a;涵盖所有关键业务流程&…