C++ std::cin

相关概念

  • 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 进行测试)。

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值