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

相关推荐
咩咦13 分钟前
C++学习笔记22:前置后置 ++/-- 和日期减日期
c++·学习笔记·运算符重载·日期类·前置++·后置++·日期减日期
计算机安禾18 分钟前
【c++面向对象编程】第40篇:单例模式(Singleton)的多种C++实现
开发语言·c++·单例模式
一个不知名程序员www1 小时前
算法学习入门---算法题DAY1
c++·算法
桀人1 小时前
C++——内存管理——new和delete的超详细解析
开发语言·c++
Shadow(⊙o⊙)1 小时前
Shell进程替换,自定义Shell解释器——字符串库函数灵活操作!
linux·运维·服务器·开发语言·c++·学习
_F_y1 小时前
树形 DP 从入门到进阶:普通树形DP、树形背包、换根DP
c++·动态规划
Hua-Jay1 小时前
OpenCV联合C++/Qt 学习笔记(二十三)----图像校正及单目位姿估计
c++·笔记·qt·opencv·学习·计算机视觉
charlie1145141912 小时前
现代C++特性指南(4)——完美转发与移动语义实战
开发语言·c++·现代c++
小白|2 小时前
cann-learning-hub:昇腾CANN社区学习中心完全指南
java·c++·算法
mirror_zAI2 小时前
C++ 仿 QQ 聊天室项目:Qt 客户端 + epoll 服务端 + Reactor 架构(含源码)
c++·qt·架构