std::basic_istream
总结
文章目录
概述
std::basic_istream
是 C++ 标准库中用于高级字符流输入操作的类模板,定义于 <istream>
头文件中。它提供格式化和非格式化输入功能,构建在 basic_streambuf
接口之上。
常用类型定义
类型 | 定义 |
---|---|
std::istream |
std::basic_istream<char> |
std::wistream |
std::basic_istream<wchar_t> |
全局对象
对象 | 描述 |
---|---|
cin |
标准 C 输入流 (stdin ) |
wcin |
宽字符标准输入流 |
核心成员函数
1. 格式化输入
- **
operator>>
**: 提取格式化数据(如整数、字符串等)
2. 非格式化输入
函数 | 描述 |
---|---|
get |
提取字符 |
peek |
读取下一个字符但不提取 |
unget |
将字符放回输入流 |
putback |
将字符放回输入流 |
getline |
提取字符直到遇到指定分隔符 |
ignore |
提取并丢弃字符直到遇到指定字符 |
read |
提取字符块 |
readsome |
提取当前可用的字符块 |
gcount |
返回最后非格式化输入提取的字符数 |
3. 流定位
函数 | 描述 |
---|---|
tellg |
返回输入位置指示器 |
seekg |
设置输入位置指示器 |
4. 其他功能
**
sync
**: 与底层存储设备同步**
swap
** (C++11): 交换流对象(除关联缓冲区外)
继承的功能
来自 std::basic_ios
状态检查
函数 | 描述 |
---|---|
good() |
检查是否无错误 |
eof() |
检查是否到达文件末尾 |
fail() |
检查是否发生错误 |
bad() |
检查是否发生不可恢复错误 |
operator! |
错误检查(fail() 的同义词) |
operator bool |
无错误检查(!fail() 的同义词) |
状态管理
rdstate()
: 返回状态标志setstate()
: 设置状态标志clear()
: 修改状态标志
来自 std::ios_base
格式化标志
标志 | 描述 |
---|---|
dec |
十进制整数 I/O |
oct |
八进制整数 I/O |
hex |
十六进制整数 I/O |
left |
左对齐输出 |
right |
右对齐输出 |
scientific |
科学计数法浮点输出 |
fixed |
固定点表示法浮点输出 |
boolalpha |
布尔值字母格式输入输出 |
流打开模式
模式 | 描述 |
---|---|
in |
打开用于读取 |
out |
打开用于写入 |
binary |
二进制模式打开 |
ate |
打开后立即定位到文件末尾 |
app |
每次写入前定位到文件末尾 |
trunc |
打开时清空内容 |
特点说明
主要用于处理字符流的高级别输入操作
同时支持格式化和非格式化输入
通过虚继承从
std::basic_ios
派生通常唯一非继承的数据成员是
gcount()
的返回值提供 sentry 类用于输入操作前的准备工作
此总结涵盖了 std::basic_istream
的主要功能和特性,适用于日常使用参考。
例子
std::basic_istream
全面用法演示
我将全面展示 std::basic_istream
的核心功能,包括格式化输入、非格式化输入、流状态管理、定位操作、自定义sentry类等高级用法。
1. 基础用法(格式化输入)
#include <iostream>
#include <sstream>
#include <iomanip>
void basic_usage() {
// 1. 基本格式化输入
std::basic_istringstream<char> iss1("42 3.14 Hello");
int i; double d; std::string s;
iss1 >> i >> d >> s;
std::cout << "Int: " << i << ", Double: " << d << ", String: " << s << "\n";
// 2. 控制输入格式
std::basic_istringstream<char> iss2("0x2A 0101");
iss2 >> std::hex >> i; // 十六进制输入
std::cout << "Hex: " << i << "\n";
iss2 >> std::oct >> i; // 八进制输入
std::cout << "Oct: " << i << "\n";
// 3. 设置输入字段宽度
std::basic_istringstream<char> iss3("123456");
char buf[4];
iss3 >> std::setw(4) >> buf;
std::cout << "Width-limited: " << buf << "\n";
}
2. 非格式化输入操作
#include <iostream>
#include <sstream>
void unformatted_input() {
std::basic_istringstream<char> iss("ABCDEFGHIJ\n123456");
// 1. get() 系列方法
char c1, c2, c3;
iss.get(c1).get(c2);
std::cout << "Got: " << c1 << c2 << "\n";
// 2. getline() 方法
char line[10];
iss.getline(line, sizeof(line));
std::cout << "Line: " << line << "\n";
// 3. read() 方法
char buffer[5];
iss.read(buffer, 4);
buffer[4] = '\0';
std::cout << "Read: " << buffer << "\n";
// 4. peek() 和 putback()
c3 = iss.peek();
std::cout << "Peek: " << c3 << "\n";
iss.putback('X');
iss.get(c3);
std::cout << "After putback: " << c3 << "\n";
// 5. ignore() 方法
iss.ignore(2, '5'); // 跳过2个字符或直到遇到'5'
iss.get(c3);
std::cout << "After ignore: " << c3 << "\n";
// 6. gcount() 获取最后读取的字符数
std::cout << "Last read count: " << iss.gcount() << "\n";
}
3. 流状态管理
#include <iostream>
#include <sstream>
void stream_state() {
std::basic_istringstream<char> iss("123 abc 456");
// 1. 基本状态检查
int val;
iss >> val;
if (iss.good()) {
std::cout << "Good state: " << val << "\n";
}
// 2. 处理失败状态
iss >> val; // 尝试读取非数字
if (iss.fail()) {
std::cout << "Failed to read\n";
iss.clear(); // 清除错误状态
}
// 3. 处理eof状态
std::string str;
while (iss >> str) {
std::cout << "Read: " << str << "\n";
}
if (iss.eof()) {
std::cout << "Reached EOF\n";
}
// 4. 综合状态检查
iss.clear();
iss.setstate(std::ios_base::badbit);
if (iss.bad()) {
std::cout << "Bad bit set\n";
}
}
4. 定位操作
#include <iostream>
#include <sstream>
void positioning() {
std::basic_istringstream<char> iss("0123456789ABCDEF");
// 1. tellg() 获取当前位置
auto pos = iss.tellg();
std::cout << "Start pos: " << pos << "\n";
// 2. seekg() 绝对定位
iss.seekg(5);
char c;
iss.get(c);
std::cout << "Char at pos 5: " << c << "\n";
// 3. seekg() 相对定位
iss.seekg(2, std::ios_base::cur);
iss.get(c);
std::cout << "Char at pos+2: " << c << "\n";
// 4. seekg() 从末尾定位
iss.seekg(-3, std::ios_base::end);
iss.get(c);
std::cout << "Char 3 from end: " << c << "\n";
// 5. 保存和恢复位置
auto save_pos = iss.tellg();
iss.seekg(0);
iss.get(c);
std::cout << "First char: " << c << "\n";
iss.seekg(save_pos);
iss.get(c);
std::cout << "Restored char: " << c << "\n";
}
5. 高级用法(sentry类)
#include <iostream>
#include <sstream>
void advanced_usage() {
std::basic_istringstream<char> iss(" Hello World");
// 1. 手动使用sentry
std::basic_istream<char>::sentry se(iss);
if (se) {
char c;
iss.get(c);
std::cout << "First non-whitespace: " << c << "\n";
}
// 2. 在自定义提取操作中使用sentry
struct Point { int x, y; };
std::basic_istringstream<char> iss2("(10,20)");
char dummy;
Point p;
iss2 >> dummy; // 读取'('
if (dummy != '(') iss2.setstate(std::ios_base::failbit);
std::basic_istream<char>::sentry se2(iss2);
if (se2) {
iss2 >> p.x >> dummy >> p.y;
if (dummy != ',') iss2.setstate(std::ios_base::failbit);
}
iss2 >> dummy; // 读取')'
if (dummy != ')') iss2.setstate(std::ios_base::failbit);
if (iss2) {
std::cout << "Point: (" << p.x << "," << p.y << ")\n";
}
}
6. 综合示例(文件处理)
#include <iostream>
#include <fstream>
#include <vector>
void file_processing() {
// 1. 创建测试文件
{
std::basic_ofstream<char> ofs("test.txt");
ofs << "10 20 30\n40 50 60\n70 80 90\n";
}
// 2. 读取文件内容
std::basic_ifstream<char> ifs("test.txt");
if (!ifs) {
std::cout << "Failed to open file\n";
return;
}
std::vector<int> values;
int val;
// 3. 读取直到EOF
while (ifs >> val) {
values.push_back(val);
// 检查流状态
if (ifs.bad()) {
std::cout << "Critical error\n";
break;
}
if (ifs.fail()) {
ifs.clear();
ifs.ignore(1); // 跳过错误字符
}
}
// 4. 输出结果
std::cout << "Read values:";
for (int v : values) {
std::cout << " " << v;
}
std::cout << "\n";
// 5. 重新定位并读取
ifs.clear();
ifs.seekg(0);
std::string line;
while (std::getline(ifs, line)) {
std::cout << "Line: " << line << "\n";
}
}
int main() {
basic_usage();
unformatted_input();
stream_state();
positioning();
advanced_usage();
file_processing();
return 0;
}
这个全面演示涵盖了:
所有主要的格式化输入操作
完整的非格式化输入方法
详细的流状态管理
全面的定位操作
高级sentry类用法
实际文件处理示例
每个示例都直接使用basic_istream及其相关组件,展示了从基础到高级的各种用法场景。