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

相关推荐
running thunderbolt16 小时前
c++:SLT容器之set、map详解
开发语言·c++
“αβ”16 小时前
网络编程套接字(三)---简单的TCP网络程序
linux·服务器·网络·c++·网络协议·tcp/ip·套接字
lingran__16 小时前
速通ACM省铜第十四天 赋源码(Coloring Game)
c++·算法
会开花的二叉树16 小时前
实战:基于 BRPC+Etcd 打造轻量级 RPC 服务 —— 从注册到调用的完整实现
网络·数据库·c++·rpc·etcd
青草地溪水旁17 小时前
设计模式(C++)详解——命令模式(1)
c++·设计模式·命令模式
青草地溪水旁17 小时前
设计模式(C++)详解——命令模式(2)
c++·设计模式·命令模式
敲上瘾17 小时前
HTTP协议工作原理与生产环境服务器搭建实战
服务器·网络·c++·网络协议·http
Zfox_17 小时前
【C++项目】微服务即时通讯系统:服务端
数据库·c++·微服务·中间件·rpc·架构·即时通讯
清朝牢弟17 小时前
基于Win系统下PCL库入门到实践:IO模块之PCD文件的读写(附详细代码)
c++·pcl·pcd
爱和冰阔落18 小时前
【C++STL详解】带头双向循环结构 + 双向迭代器,核心接口 + 排序效率 + 避坑指南
开发语言·c++·经验分享