当前位置: 首页 > article >正文

C++ std::cin

C++ std::cin

  • 相关概念
  • 使用
    • 1. 一个常见的使用场景:
    • 2. 用于静态对象的构造和析构函数中,访问标准输入/输出流是安全的。
    • 3. 作为 *while* 语句的条件
    • 4. 配合 *get*、*getline* 使用

相关概念

  • istream 一个class,提供输入操作。
  • cin 一个 istream 对象,用于从标准输入读取数据。
  • >> 运算符,用于从一个 istream 对象读取输入数据。

【注】cin 中的字符 ‘c’ 指 ‘character’,“cin” 就是 ‘character input’ 的意思

std::cin 是一个全局对象,与标准C输入流 stdin 关联。

使用

1. 一个常见的使用场景:

int main() {
	/*
	...
	 */
	int ival;
	cin >> ival;
	/*
	...
	 */

	return 0;
}

支持多类型输入:

int main() {
	int iage;
	std::string strname;
	std::cout << "Enter 'name' and 'age': ";
	std::cin >> strname >> iage;
	std::cout << "Name: " << strname 
			<< "\t" << "Age: " << iage << std::endl;

	return 0;
}

因为 cin 会跳过空白字符比如 空格回车,所以虽然在同一行输入了名字和类型,但是它们会分开保存到对应的变量中:

运行结果

2. 用于静态对象的构造和析构函数中,访问标准输入/输出流是安全的。

#include<iostream>
struct UserDefinedStruct{
	int m_ival;
	UserDefinedStruct() {
		std::cout << "Enter ival: ";
		std::cin >> m_ival;
	}
};
// 定义一个静态对象
UserDefinedStruct uds;

int main() {
	std::cout << "uds.m_ival is "
			<< uds.m_ival
			<< std::endl;

	return 0;
}

3. 作为 while 语句的条件

int ival;

while(cin >> ival) {
	/*
	 ...
	 */
}

cin 操作的对象是一个 int 变量,输入运算符期待读取一个 int,当输入不符合期待时(比如输入字符 ‘a’),cin 就会进入错误状态,因此跳出循环。

那么 cin >> ival 为什么可以作为 while 的条件?
查看操作符 >> 的函数定义:

basic_istream& operator>>( int& value );

也就是说,basic_istream 在特定上下文中是可以隐式转换为一个 bool 值。我们知道 IO 操作的一个问题就是它有可能会产生问题。。。因此 IO 类中定义了一些函数和标志以便于使用者访问和操纵流的条件状态,参看 C++ Primer 第五版

C++ Primer IO库条件状态

cin >> ival 之所以可以作为 while 语句的条件,是因为 istream 重载了 operator bool,而 operator bool 会在 fail()false 并且还处于 IO ready state 的时候返回 true
cin >> ival 遇到键入的 ‘a’ 时,因为 ‘a’ 并不是理想的输入,failbit 置位,又因为是在 while 的条件中,这是一个 bool 语境,因此调用了 operator bool, 而 operator bool 中又调用了 fail(),因为 fail() 返回 true,所以 operator bool 返回 false。。。因此退出了循环(为什么不调用 good() 呢。。。)
这个转换是隐式的,咋一看会很迷惑。

前面的例子都是通过 cin 搭配操作符 << 来使用的,外部输入的数据被保存在 cin 的缓冲区中,通过操作符 “<<” 把数据从 cin 中提取出来。操作符 >> 表现为带格式的输入。
在不带格式的输入场景下,可以使用 get 或者 getline

4. 配合 getgetline 使用

cinget 或者 getline 的组合使用方式十分相似:

// 程序 1
#define MAX_LEN	20

int main() {
	char ch[MAX_LEN];
	std::cout << "Enter: ";
	std::cin.get(ch, MAX_LEN);
	std::cout << "Entered: " << std::endl;

	// 这里用于输出计数
	for(int i = 0; i != 4; ++i) {
		for (int j = 0; j != 10; ++j) {
			std::cout << j;
		}
	}

	std::cout << '\n';
	std::cout << ch;

	return 0;
}

输入字符串在长度限制内:
输入字符串在长度限制内
输入字符串超出长度限制:
输入字符串超出长度限制

// 程序 2
#include<iostream>

int main() {
	char strname[32];
	char straddr[256];

	std::cout << "Enter your name: ";
	std::cin.getline(strname, 32);

	std::cout << "Enter your address: ";
	std::cin.getline(straddr, 256);

	std::cout << strname << "'s address: " << straddr << std::endl;

	return 0;
}

不同的是 get 每次读取一整行并把换行符留在输入队列中,因此在连续多次输入的场景下需要在每次 get 用户输入后再调用一次 get 读取换行符,或者调用 ignore 忽略换行符。而 getline 每次读取一整行后会把换行符丢弃(可以修改程序 2 中的 getline 进行测试)。


http://www.kler.cn/news/11709.html

相关文章:

  • 无限制翻译软件-中英互译字数无限
  • 2023软件测试最难求职季,哪些测试技能更容易拿到offer?
  • 第十四届蓝桥杯C++省赛B组 补题(3 - 10)
  • 网络安全之从原理看懂 XSS
  • 4月想跳槽的同学,没有更好的选择,可以去美团
  • pmp证书报考流程+pmp备考+pmp学习干货+pmp指南汇总
  • Socket套接字编程(实现TCP和UDP的通信)
  • 随想录Day55--动态规划: 392.判断子序列 , 115.不同的子序列
  • HTTP协议详解(一)
  • C ++匿名函数:揭开C++ Lambda表达式的神秘面纱
  • CloudCompare如何使用基础功能?
  • Java这么卷,还有前景吗?
  • 接口面试题
  • LeetCode 1041. 困于环中的机器人
  • namedtuple 命名元祖
  • 让PyTorch训练速度更快,你需要掌握这17种方法
  • 倍增?最近公共祖先?——从定义到实现,帮你一步步吃掉它!
  • Python零基础教程
  • IO-IO基础
  • day7 线程的取消和清理
  • Python基础-08 函数基础
  • Python-代码阅读(1)-funcs.py
  • 00.如何学习spring
  • Dapper——分布式跟踪系统
  • JavaScript基础05 - JSON
  • Node fs模块
  • 一个lapack网页 dstedc DSYTRD cusolverDnCheevd
  • Java开发 - 公共字段的自动填充
  • 第十四天本地锁、Redis分布锁、Redisson锁三者的区别
  • 什么是MVVM?