# `std::basic_istream`总结

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及其相关组件,展示了从基础到高级的各种用法场景。

相关推荐
橘颂TA8 分钟前
【测试】高效浏览器操作:基础功能与优化设置大全
c++·功能测试·职场和发展·测试·web测试
一只小小的芙厨11 分钟前
寒假集训笔记·以点为对象的树形DP
c++·算法
艾莉丝努力练剑31 分钟前
hixl vs NCCL:昇腾生态通信库的独特优势分析
运维·c++·人工智能·cann
我在人间贩卖青春36 分钟前
C++之new和delete
c++·delete·new
Trouvaille ~1 小时前
TCP Socket编程实战(三):线程池优化与TCP编程最佳实践
linux·运维·服务器·网络·c++·网络协议·tcp/ip
June`1 小时前
高并发网络框架:Reactor模式深度解析
linux·服务器·c++
小镇敲码人1 小时前
剖析CANN框架中Samples仓库:从示例到实战的AI开发指南
c++·人工智能·python·华为·acl·cann
刘琦沛在进步2 小时前
【C / C++】引用和函数重载的介绍
c语言·开发语言·c++
我在人间贩卖青春2 小时前
C++之this指针
c++·this
云姜.2 小时前
java多态
java·开发语言·c++