std::basic_istream
總結
文章目錄
- `std::basic_istream`總結
- 概述
- 常用類型定義
- 全局對象
- 核心成員函數
- 1. 格式化輸入
- 2. 非格式化輸入
- 3. 流定位
- 4. 其他功能
- 繼承的功能
- 來自 `std::basic_ios`
- 狀態檢查
- 狀態管理
- 來自 `std::ios_base`
- 格式化標志
- 流打開模式
- 特點說明
- 例子
- `std::basic_istream`全面用法演示
- 1. 基礎用法(格式化輸入)
- 2. 非格式化輸入操作
- 3. 流狀態管理
- 4. 定位操作
- 5. 高級用法(sentry類)
- 6. 綜合示例(文件處理)
概述
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. 手動使用sentrystd::basic_istream<char>::sentry se(iss);if (se) {char c;iss.get(c);std::cout << "First non-whitespace: " << c << "\n";}// 2. 在自定義提取操作中使用sentrystruct 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. 讀取直到EOFwhile (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及其相關組件,展示了從基礎到高級的各種用法場景。