【C++中cin、cin.get()、cin.getline()、getline() 的区别】
文章目录
- 引入
- cin
- 基本用法
- 输入多个变量
- 换行符存放在缓冲区中
- cin.get()
- 基本用法
- 重载函数
- 换行符残留在缓冲区中
- cin.getline()
- 基本使用
- 重载函数
- 换行符不会残留在缓冲区中
- string 流中的 getline()
- 总结
- 用法总结
- 几个输入实例
- 输入格式
- 输入格式
- 输入格式
- 输入格式
- 输出格式
- 写在最后
引入
在 ACM 模式的题目编程中,我们需要自己解决程序的输入与输出问题。我们自己解决程序的输入其实就是从键盘输入数据,然后将输入的数据传递我们定义的变量,其简要过程如下:
- 使用输入流
cin
或其他输入函数从键盘读取数据时,程序会向操作系统发出请求以获取输入,就是程序运行后终端(屏幕)上那个一闪一闪输入提示符; - 敲击键盘输入几个字符;
- 当我们想要结束字符的输入时,按下回车键;
- 操作系统将用户输入的数据一次性放入输入缓冲区中;
- C++ 程序通过
cin
或其他输入流来读取缓冲区中的数据。
代码运行时需要的变量也许是一个字符,也许是一个整型数字,也许是一个带有空格的字符串等等,这些我们都可以通过键盘输入然后按下回车键放入输入缓冲区,但是不同的 输入流 或者 输入函数 从缓冲区读取的数据效果也是不同的。
- 如果想在以空格分隔的缓冲区数据中读取多个数据,我们应该使用什么样的 输入流 或者 输入函数 ?
- 如果想在缓冲区中读取指定字符之前的数据,我们应该使用什么样的 输入流 或者 输入函数 ?
- 如果想在缓冲区中按行读取数据,我们应该使用什么样的 输入流 或者 输入函数 ?
如果,你可以轻松应对以上三个问题,那么厉害了,你已经基本掌握cpp中的常用的从标准输入流读取数据的操作了,也可以看看这篇博文回顾回顾嘛。如果对以上问题的答案还不太清楚,那么同学一定要好好看看这篇文章啊。
接下来就步入正题,看一下不同的 输入流 或者 输入函数 从缓冲区读取数据具有怎么样的不同效果。
cin
基本用法
我们先来介绍 C++ 中最常用的一个标准输入流对象 cin。
我们常用 cin >> num
来从缓冲区中读取数据到 num
中,num
的变量类型可以是多种类型,最常用的有 int
、string
、char
、double
、float
等等。
先看一个小例子:
#include <iostream>
using namespace std;int main() {int n;cin >> n;cout << "n = " << n << endl;return 0;
}
在这个示例中,我们从键盘输入了一个整型字符(比如说 9
),按下回车键,整型字符会被存入到缓冲区中,然后使用 cin
来读取缓冲区的数据,最后通过标准输出流 cout
将 "n = 9"
输出到终端窗口。
cin 从缓冲区中读数据,读取的是第一个非空白字符开始到第一个结束符之间的字符串。这个结束符可以是空格,也开始是制表符,也可以是换行符。空格、制表符、换行符是内置的 cin 的结束符,如果想用其他的字符来提前结束读取数据,需要自定义。
输入多个变量
cin
是直接从缓冲区读取数据的,如果缓冲区中还有数据,我们就不需要请求键盘输入,直接从缓冲区读取数据。比如下面的例子:我们在输入第一个字符串之后用空格隔开,然后输入了第二个字符串。对应的代码以及输出结果如下所示。
#include <iostream>
using namespace std;int main() {char s[100];cout << "请输入字符串:" << endl;cin >> s;cout << s << endl;cin >> s;cout << s << endl;return 0;
}

由于 cin
在遇到空格或者制表符(/tab
)时,会停止读取输入,因此第一个 cin
只会读取第一个字符串(第一个非空白字符开始到下一个空格字符结束之间的字符串)。这时候缓存区中还有残留的数据,因此下一个 cin
会直接从缓冲区中读取数据,而不会请求输入。
利用该原理,我们可以从以空格或者制表符为分隔符的缓冲区数据中读取多个数据。
换行符存放在缓冲区中
按下相应的结束符,才会从缓冲区读取数据到变量中,cin
每次从缓冲区中读取一个字符串,以空格作为字符或者字符串的分隔符。需要注意的是最后一个换行符会放在缓冲区中。比如下面的示例,该示例中我们使用 cin.get() 从缓冲区中读取单个字符。
#include <iostream>
using namespace std;int main() {char s1[100], s2[100], ch;cout << "请输入字符串:" << endl;cin >> s1 >> s2;cout << s1 << endl;cout << s2 << endl;cin.get(ch);cout << (int)ch << endl;return 0;
}
我们从键盘输入 "cc ff"
,然后按下回车键,缓冲区中的数据为 "cc ff\n"
,我们将缓冲区的字符串 "cc"
和 "ff"
分别传给 s1
和 s2
,换行符传给 ch
。最后的输出结果如下图所示,因为换行符的 ASCII 码为 10
,所以最后会输出一个 10
。

cin.get()
基本用法
cin.get()
是C++标准库中的函数,用于从输入流中获取字符,包括空白字符(如空格、制表符和换行符)。与 cin
不同,cin.get()
不会将制表符、空白字符(空格)视为终止输入的标志,因此您可以使用它来获取包括空白字符在内的整行文本。默认情况下,cin.get()
使用换行符(\n
)作为定界符(终止读取数据的结束符),表示读取到换行符时结束。
运行以下代码,然后输入 123 456
,再按下回车键,输出结果如图所示:
#include <iostream>
using namespace std;int main() {char s1[100];cin.get(s1, 100);cout << s1 << endl;return 0;
}

类似的代码,如果我们使用 cin
读取缓冲区的数据,那将只会输出 "123"
。
重载函数
在头文件 中定义的 get() 函数有以下几种重载形式:
// single character (1) 从标准流中读取单个字符;
int get();
istream& get (char& c);// c-string (2) 从标准流中读取字符串并存储在c标准的s字符串中;
istream& get (char* s, streamsize n);
istream& get (char* s, streamsize n, char delim);// stream buffer (3)
istream& get (streambuf& sb);
istream& get (streambuf& sb, char delim);
我们最常用的是使用cin.get() 从标准输入流中读取单个字符以及读取多个字符存储在c标准的字符串中。
换行符残留在缓冲区中
cin.get() 与 cin 都是遇到相应的结束符才会结束从缓冲区读取数据,它们都不对换行符进行处理,换行符都会残留在缓冲区中。如果下次不想从上一次的缓冲区中读取数据,可以使用 cin.ignore() 忽略上一个缓冲区中的数据,或者使用 cin.getlin()。
cin.getline()
基本使用
cin.getline()
是C++标准库中的函数,用于从输入流中读取一行文本,并允许您指定一个定界符字符来结束读取。默认的定界符是换行符 (\n
),表示读取到换行符时结束。但您可以通过提供第三个参数来指定自定义的定界符字符。
重载函数
在头文件 中定义的 getline 函数有以下两种重载形式:
istream& getline (char* s, count n);
istream& getline (char* s, count n, char delim);
作用是: 从istream中读取至多 n
个字符(包含结束标记符’\0’)保存在 s
对应的数组中,实际上只从输入流中最多读取 n-1
个字符到数组 s
中,因为最后一个字符必须是结束标志符 '\0'
,也就是c语言中所有的字符串中的最后一个字符 。
换行符不会残留在缓冲区中
cin.getline() 与 cin >> 、cin.get() 的使用基本一致,唯一的区别就是 cin >> 、cin.get() 遇到结束符终止从缓存区读取数据时,换行符会残留在缓冲区中,而使用 cin.getline() 换行符不会残留在缓冲区中。
现在我们使用getline来从标准输入中读取数据:
#include <iostream>using namespace std;int main() {char str[100];cin.getline(str, 100);cout << "str = " << str << endl;char c = cin.get();cout << (int)c << endl;return 0;
}
我们运行以上代码,输入任意一个字符串,比如 “123 589”,按下回车键,屏幕上会出现 “str = 123 589”(左图)。我们再按下回车键,屏幕上才会出现 10
(右图)。


如果,我们执行以下这段代码:
#include <iostream>using namespace std;int main() {char str[100];cin.get(str, 100);cout << "str = " << str << endl;char c = cin.get();cout << (int)c << endl;return 0;
}
输出的结果为:

为什么会有如此差异,因为使用 cin.getline() ,换行符不会残留在缓冲区中。
在第一段代码中,我们还需要从缓冲区读取一个字符,缓冲区中已经没有任何字符了,因此会有提示输入符出现,我们按下回车键(换行符),屏幕上输出了我们按下的回车键(换行符)的 ASCII 码。
在第二段代码中,我们使用 cin.get() 来从标准输入读取数据,按下回车键(换行符),缓冲区中的字符串传给了 str
。这时候,换行符会残留在缓冲区中,这个时候又需要从缓冲区中读取一个字符,于是就顺理成章的将换行符传给了 c
,屏幕上也就会接着输出换行符的 ASCII 码了。
string 流中的 getline()
头文件中也有 getline() 函数,它们的使用与 中的用法基本一致,只有三点不同:
- 头文件的不同;
- getline() 中的多了第一个参数
istream is
,通常填上cin
,表示的是从标准输入流中读取数据; - getline() 中的接收字符串变量为
string
,而不是char*
。在C++代码中,建议使用getline(),因为接收字符串的变量是string
,是可以动态扩展的类型。
除了以上三点不同之外,其他的用法都与 中的 cin.getline()
用法一致,包括 getline() 不会将换行符残留在缓冲区中。
总结
用法总结
cin.get() 和 cin.getline() 是输入流中的,使用之前需要包含头文件 。cin 是输入输出流中的,使用之前需要包含头文件 。getline() 是字符串流的,使用之前需要包含头文件 。
从标准输入读取单个或者是多个变量(以空格、制表符、换行符隔开),尤其是整型变量,或者从多行读取整型变量到数组,使用 cin。
从标准输入读取单个字符,推荐使用输入流中的 cin.get()。
从标准输入读取单行字符串、多行字符串的,推荐使用字符串流中的 getline()。
cin、cin.get() 会将换行符残留在缓冲区中,getline() 和 cin.getline() 不会。
几个输入实例
输入格式
第一行有两个非负整数 m,n。他们分别表示数组的长度和宽度。
接下来 m 行,每行有 n 个整数。
在ACM编程下,最常遇到的就是从键盘输入 m 行 n 列数据到数组了,以下是从键盘输入 int
整型数据的代码。
#include <iostream>
#include<vector>using namespace std;int main() {int m, n;cin >> m >> n;vector<vector<int>> grids(m, vector<int>(n));for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {cin >> grids[i][j];}}/* 此段代码用来测试输入是否正确for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {cout << grids[i][j] << " ";}cout << endl;}*/return 0;
}
我们在命令行窗口输入数据的方法有两种:
- 第一种:在一行中输入所有的数据,第一个数是行数m,第二个数是列数n,接下来的是第一行的所有列中的数字,然后是第二行中的所有列的数字,直到输入完所有m行n列的数字(相邻两个数字之间都用空格隔开);
- 第二种:在第一行输入行数m和列数n(以空格隔开),按下回车键,接下来的m行每一行输入n个数字,每输完一行数字就按一下回车键;
- 最后按下的那个回车键会存储在缓冲区中。
输入格式
第一行包含两个正整数 m , n m,n m,n,分别表示 A A A 串和 B B B 串的长度。
第二行为一个长度为 m m m 的字符串 A A A。
第三行为一个长度为 n n n 的字符串 B B B。
两个串均仅由小写字母和 * \texttt * * 组成,其中 * \texttt * * 表示相应位置已经残缺。
#include <iostream>
#include <string>
using namespace std;int main() {int m, n;string A, B;cin >> m >> n >> A >> B;// // 测试输入是否正确// cout << m << " " << n << endl;// cout << A << " " << B << endl;return 0;
}
输入格式
多行字符串。
每一行输入一个含有空格的字符串,输入多行,遇到 “END” 结束输入。
#include <iostream>
#include <string>
#include <vector>
using namespace std;int main() {string str;vector<string> strs;getline(cin, str);while (str != "END" ) {strs.push_back(str);getline(cin, str);}// for testfor (auto str : strs) {cout << str << endl;}return 0;
}
输入格式
输入在一行中给出不知道多少个绝对值不超过1000的整数。
输出格式
在一行中输出最后一次出现的 “250” 是第几个数字(计数从1开始)。如果没有出现 “250” 这个数,输出为 0。
// #include <iostream>// using namespace std;// int main()
// {
// int ct = 0;
// int a, pos = 0;
// do
// {
// ct++;
// cin >> a;
// if (a == 250)
// pos = ct;
// }
// while (cin.get() != '\n');
// cout << pos;
// return 0;
// }#include <iostream>using namespace std;int main() {int cnt = 0;int a, pos = 0;while (cin.get() != '\n') {++cnt;cin >> a;if (a == 250) {pos = cnt;}}cout << pos;return 0;
}
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。
相关文章:

【C++中cin、cin.get()、cin.getline()、getline() 的区别】
文章目录 引入cin基本用法输入多个变量换行符存放在缓冲区中 cin.get()基本用法重载函数换行符残留在缓冲区中 cin.getline()基本使用重载函数换行符不会残留在缓冲区中 string 流中的 getline()总结用法总结几个输入实例输入格式输入格式输入格式输入格式 输出格式 写在最后 引…...

SSH连接华为交换机慢
ssh连接交换机慢是因为交换计算密钥算法阶段默认使用安全性更高的秘钥,由于性能问题导致连接比较慢,如一台华为S5735S-L24T4S-QA2的交换机默认使用如下秘钥,安全行由高到低。 ssh server key-exchange dh_group16_sha512 dh_group15_sha512 …...

Web攻防03_MySQL注入_数据请求
文章目录 PHP-MYSQL-数据请求类型1、数字型(无符号干扰)2、字符型(有符号干扰)3、搜索型(有多符号干扰)4、框架型(有各种符号干扰) PHP-MYSQL-数据请求方法数据请求方法GET:POST:Coo…...

JS加密/解密那些必须知道的事儿
一直以来,字符串的编码问题对于新手程序员来说,或者平常不太涉猎这方面的程序员来说,是犹如灵异学一样的存在。经常会遇到莫名其妙的编码问题,导致的各种的无法理解的错误。 今天,本问就来介绍一下作者所知晓的一切…...

搭建伪分布式Hadoop
文章目录 一、Hadoop部署模式(一)独立模式(二)伪分布式模式(三)完全分布式模式 二、搭建伪分布式Hadoop(一)登录虚拟机(二)上传安装包(三…...

【C++】特殊类的设计(只在堆、栈创建对象,单例对象)
🌏博客主页: 主页 🔖系列专栏: C ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 文章目录 一、请设计一个类,只能在堆上创建对象二、 请设计一个类,只能…...

分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测
分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于GRU-AdaBoost门控循环单元结…...

【Spring Boot项目】根据用户的角色控制数据库访问权限
文章目录 简介方法一添加数据库依赖配置数据库连接创建用户角色表创建Spring Data JPA实体和仓库实现自定义的网关过滤器配置网关过滤器几个简单的测试API 方法二创建数据库访问接口实现数据库访问接口创建用户角色判断逻辑创建网关过滤器配置网关过滤器 总结 简介 在一些特定…...

EthernetIP 转MODBUS RTU协议网关连接FANUC机器人作为EthernetIP通信从站
远创智控YC-EIPM-RTU网关产品是一款高效的数据采集工具,它可以通过各种数据接口与工业领域的仪表、PLC、计量设备等产品连接,实时采集这些设备中的运行数据、状态数据等信息。采集到的数据经过整合和运算等操作后,可以被传输到其他设备或者云…...

如何注册微信小程序
如何注册微信小程序 前言 因为最近沉迷和朋友们一起下班去打麻将,他们推荐了一个计分的小程序,就不需要每局都转账或者用扑克牌记录了,但是这个小程序不仅打开有广告,各个页面都植入了广告,用起来十分不适。 于是我…...

移动App安全检测的必要性,app安全测试报告的编写注意事项
随着移动互联网的迅猛发展,移动App已经成为人们日常生活中不可或缺的一部分。然而,虽然App给我们带来了便利和乐趣,但也伴随着一些潜在的安全风险。黑客、病毒、恶意软件等威胁着用户的隐私和财产安全,因此进行安全检测就显得尤为…...

DVWA-JavaScript Attacks
JavaScript Attacks JavaScript Attack即JS攻击,攻击者可以利用JavaScript实施攻击。 Low 等级 核心源码,用的是dom语法这是在前端使用的和后端无关,然后获取属性为phrase的值然后来个rot13和MD5双重加密在复制给token属性。 <script&…...

算法通关村第二关|白银|链表反转拓展【持续更新】
1.指定区间反转 1.1 头插法:将区间内遍历到的结点插入到起始处之前。 public ListNode reverseBetween(ListNode head, int left, int right) {ListNode dummyNode new ListNode(-1);dummyNode.next head;ListNode pre dummyNode;// 将pre移动到区间的前一位&a…...

开发者职场“生存状态”大调研报告分析 - 第四版
听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…...

代码与细节(一)
在用到 Java17的新特性 Unmodifiable Lists 时不知道你是否和我有同样的惊讶 为什么弄了这么多重载方法? 先说结论:为了性能。 其实一细想,都能想明白:varargs(可变参数) 的背后是数组的内存分配和初始化,相比正常的…...

AI绘画使用Stable Diffusion(SDXL)绘制中国古代神兽
一、引言 说到神奇异兽,脑海中首先就会跳出我国古代神话传说中的各种神兽。比如青龙、白虎、朱雀、玄武,再比如麒麟、凤凰、毕方、饕餮等等,这些都是大家耳熟能详的的神兽。 这些神兽不仅体现了人们丰富的创造力和想象力,更是我…...

老卫带你学---leetcode刷题(148. 排序链表)
148. 排序链表 问题: 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1:输入:head [4,2,1,3] 输出:[1,2,3,4]示例 2:输入:head [-1,5,3,4,0] 输出:[-1…...

21.1 stm32使用LTDC驱动LCD--配置说明
本文讲解如何配置LTDC驱动LCD的参数配置,以及CubeMx参数配置说明 本文使用的是淘宝买的一块带电容触摸的液晶显示屏:5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911 说实话,价格还是相对挺便宜的,值得入手…...

zabbix监控nginx的状态页面
zabbix监控nginx的状态页面 文章目录 zabbix监控nginx的状态页面1.环境说明2.所涉及到的知识点3.在nginx主机上安装zabbix_agent4.开启nginx状态显示页面5.进入zabbix的web页面配置主机,监控项,触发器5.1.添加主机5.2.创建监控项5.3.创建触发器 1.环境说…...

C语言初学者工具选择:vscode + MSYS2 + cmake 搭建 C环境
文章目录 前言1. MSYS2 安装1. 下载安装包2. 安装3. pacman 换清华大学源4. 安装 mingw-w64 toolchain 和 cmake ninja5. 将 toolchain 加入系统环境变量 2. 设置 vscode1. 必要的插件2. 一个简单的 vscode cmake 项目 最后C数据结构与算法CMake 前言 网上关于使用 vscode 配…...

【四:httpclient的使用】
目录 1、Demo案例2、请求一个带cookies的get请求3、请求一个带cookies的post请求案例一,案例二的properties的配置 1、Demo案例 public class MyHttpClient {Testpublic void test1() throws IOException {//用来存放我们的结果String result;HttpGet get new Htt…...

在innodb引擎中,count(*)、count(1)、count(主键)、count(字段)哪个性能最高?
在InnoDB引擎中,这四种计数值的效率高低取决于具体的数据库和数据表结构,无法一概而论哪个性能最高。不过,一般情况下可以按照以下顺序进行选择: count():统计所有行的数量。由于InnoDB引擎的行锁是锁住整行ÿ…...

华为OD 跳格子2(200分)【java】B卷
华为OD统一考试A卷B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击此链接进入:…...

javascript/python 笔记: folium feature group自动切换
1 python部分 python部分只能是静态的结果 1.1 导入库 import folium import math 1.2 数据 cell_lst表示基站位置,location_lst表示 用户实际位置(均为伪数据) cell_lst[[1.341505, 103.682498],[1.342751, 103.679604],[1.341505, 10…...

Python中的元组
Python 元组 Python 的元组与列表类似,不同之处在于元组的元素不能修改。以下是关于Python元组的一些基本信息: 元组的使用:元组是一个不可变的序列类型,使用小括号 () 来定义。元组没有增加元素append、修改元素、删除元素pop的…...

在云计算环境中,如何利用 AI 改进云计算系统和数据库系统性能
文章目录 前言一、关于唐明洁教授二、AI for System2.1 面向分布式作业的人工智能2.1.1 现阶段企业云计算系统环境所遇到的普遍痛点2.1.2 云计算系统环境所遇到的普遍痛点的解决方案(一)Google Autopilot Eurosys 2021方案(Pod级别࿰…...

OpenP2P实现内网穿透远程办公
OpenP2P是一个开源、免费、轻量级的P2P共享网络。你的设备将组成一个私有P2P网络,里面的设备可以直接访问其它成员,或者通过其它成员转发数据间接访问。如果私有网络无法完成通信,将会到公有P2P网络寻找共享节点协助通信。 相比BT网络用来共享…...

黑白棋(Othello, ACM/ICPC World Finals 1992, UVa220)rust解法
你的任务是模拟黑白棋游戏的进程。黑白棋的规则为:黑白双方轮流放棋子,每次必须让新放的棋子“夹住”至少一枚对方棋子,然后把所有被新放棋子“夹住”的对方棋子替换成己方棋子。一段连续(横、竖或者斜向)的同色棋子被…...

MySQL中如何进行表的优化和压缩?
在MySQL中,可以通过以下方式进行表的优化和压缩: 使用合适的存储引擎(Storage Engine):MySQL提供了多种存储引擎,如InnoDB、MyISAM等。不同的存储引擎在表的优化和压缩方面有不同的特点。例如,I…...

【Java】Jsoup格式化html问题(文本空格折叠等)解决方法
问题说明 Jsoup格式化html文本时,如: Document document Jsoup.parse(html);这里在对html进行格式化的时候会将如下内容: <p> aaa </p>解析成如下格式: <p> aaa </p>即空格折叠问题ÿ…...