C++ 标准输入流 std::cin 完整详解
·
C++ 标准输入流 std::cin 完整详解
一、基础概念
- 头文件
#include <iostream>
- 命名空间
标准输入流对象cin属于std命名空间,两种使用方式:
// 方式1:每次加std::
std::cin >> num;
// 方式2:全局引入命名空间(工程/练习常用)
using namespace std;
cin >> num;
- 本质
std::cin是istream类的全局实例,绑定键盘缓冲区;所有输入先存入内存缓冲区,程序再从缓冲区读取数据。
配套输出流:std::cout。
二、提取运算符 >>(基础读取)
1. 特性
- 自动跳过空白字符:空格
、换行\n、制表符\t; - 按数据类型自动解析,遇到空白停止读取;
- 支持链式连续读取。
2. 示例代码
#include <iostream>
#include <string>
using namespace std;
int main() {
int a;
double b;
char ch;
string str;
// 链式读取
cin >> a >> b >> ch >> str;
cout << a << " " << b << " " << ch << " " << str;
return 0;
}
输入示例:10 3.14 A hello,全部正常读取。
3. 缺陷
读取字符串时无法接收带空格内容,输入 hello world 只会读到 hello,剩余 world 留在缓冲区。
三、整行读取 getline()(读取含空格字符串)
1. 函数原型
istream& getline(istream& is, string& str);
作用:读取一整行,直到换行符 \n 为止,换行符会被丢弃,不存入字符串。
2. 基础示例
string s;
getline(cin, s);
cout << s;
输入 I love C++ 可完整输出。
3. 经典坑:cin >> 与 getline 混用
cin >> 读取数字/字符后,回车 \n 残留在缓冲区,后续 getline 会直接读到空字符串。
解决方案:cin.ignore() 清空换行。
int num;
cin >> num;
cin.ignore(); // 吃掉缓冲区残留的换行
string s;
getline(cin, s);
四、cin 常用成员函数(缓冲区操作)
1. cin.get()
两种重载:
int cin.get():读取缓冲区任意单个字符(空格、回车全部读取)
char c = cin.get();
istream& cin.get(char& ch)
char c;
cin.get(c);
2. cin.ignore(个数, 终止字符)
丢弃缓冲区指定数量字符,遇到终止字符停止,常用于清换行:
cin.ignore(1000, '\n'); // 最多丢弃1000个字符,直到遇见回车
3. cin.peek()
偷看缓冲区下一个字符,不取走,返回ASCII码:
if (cin.peek() == '\n')
cout << "下一个是换行";
4. cin.putback(ch)
把字符放回输入缓冲区,用于回退读取。
五、cin 状态标记(输入错误处理核心)
cin 内部维护4种状态位,读取失败(如输入字母给int变量)会触发错误标记,流直接锁死,无法继续读取。
| 状态函数 | 作用 |
|---|---|
cin.good() |
流正常,无错误 |
cin.fail() |
格式错误(类型不匹配,如数字读入字母) |
cin.bad() |
严重IO硬件错误,流损坏 |
cin.eof() |
读到文件/输入末尾 |
完整容错模板
#include <iostream>
using namespace std;
int main() {
int x;
while (true) {
cout << "请输入整数:";
cin >> x;
if (cin.fail()) {
cout << "输入非法,请重新输入\n";
cin.clear(); // 1. 清除错误标记,解锁输入流
cin.ignore(999, '\n'); // 2. 清空错误的残留字符
} else {
cout << "输入正确:" << x;
break;
}
}
return 0;
}
六、缓冲区原理
- 键盘输入内容不会直接给程序,先存入输入缓冲区;
cin >>/getline从缓冲区取数据,缓冲区空时程序阻塞等待键盘输入;- 换行、空格是读取分隔标记;
- 读取失败时缓冲区脏数据残留,必须
ignore清理,否则循环持续报错。
七、字符数组老式读取(C风格字符串)
cin.getline(char数组, 长度)
char buf[100];
cin.getline(buf, 100); // 最多读取99个字符,自动补'\0'
区别:
std::getline(cin, string):C++ string专用;cin.getline(字符数组, 长度):兼容C char[]。
八、标准输入重定向(进阶)
可以不从键盘读,直接读取文件:
#include <fstream>
ifstream fin("data.txt");
cin.rdbuf(fin.rdbuf()); // 将cin绑定文件,cin自动读文件内容
九、核心对比总结
cin >>- 优点:简单自动解析数字、字符串;
- 缺点:空格截断,不能读整行;
getline(cin, str)- 优点:读取整行含空格;
- 缺点:需处理
cin >>遗留换行;
cin.get()- 优点:读取空格、回车;
- 缺点:只能单字符读取。
更多推荐
所有评论(0)