# `std::basic_istream`总结

发布于:2025-08-31 ⋅ 阅读:(27) ⋅ 点赞:(0)

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;
}

这个全面演示涵盖了:

  1. 所有主要的格式化输入操作

  2. 完整的非格式化输入方法

  3. 详细的流状态管理

  4. 全面的定位操作

  5. 高级sentry类用法

  6. 实际文件处理示例

每个示例都直接使用basic_istream及其相关组件,展示了从基础到高级的各种用法场景。


网站公告

今日签到

点亮在社区的每一天
去签到