首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ STL 輸入輸出流全攻略:iostream、fstream 與 stringstream

     編輯:關於C++

流體系繼承圖譜

C++ I/O 庫以 ios_base 為根,basic_ios 模板化字符類型,istream/ostream 分別提供輸入/輸出,iostream 多重繼承雙向流。文件流 ifstream/ofstream/fstream、字符串流 istringstream/ostringstream/stringstream 對應不同數據源/池。

標準輸入輸出流(iostream)

基本操作

int i; float f; char s[20];
cin >> i >> f >> s;           // 連續提取,空白分隔
cout << "i=" << i << '\n'
     << "f=" << f << '\n'
     << "s=" << s << endl;     // endl 刷新緩衝區

讀取整行:get/getline

函數原型行為
get()int get()讀單字符,返回 ASCII 值,EOF 返回 EOF
getistream& get(char* buf, size_t n, char delim='\n')讀至 delim 或 n-1 字符,**不提取 delim**,留在流中
getlineistream& getline(char* buf, size_t n, char delim='\n')讀至 delim 或 n-1 字符,**提取並丟棄 delim**
char s1[100], s2[100];
cin.get();              // 讀取並丟棄第一個字符(如 '?')
cin.get(s1, 100, '\t'); // 讀至 Tab,Tab 留在流
cin.getline(s2, 100);   // 讀至換行,換行被丟棄
// s1="How are you?" s2="Fine,thank you!"

流狀態檢測與錯誤處理

每個流對象維護 iostate 位掩碼:

標志位常量含義檢測函數
goodbit0無錯誤good()
eofbit1到達文件末尾eof()
failbit2邏輯錯誤(如類型不匹配),流可繼續fail()
badbit4系統級錯誤(如磁盤故障),流不可用bad()
int x;
cin >> x;
if (cin.good()) { /* 成功 */ }
else if (cin.fail()) {
    cin.clear();      // 重置狀態位
    cin.get();        // 丟棄非法字符
    // 繼續讀取
}

文件流(fstream)

打開模式組合

ofstream out("data.txt", ios::out | ios::trunc); // 寫入,截斷
ifstream in("data.txt", ios::in);                // 讀取
fstream io("data.bin", ios::in | ios::out | ios::binary); // 讀寫二進制
模式含義
ios::in讀取
ios::out寫入
ios::app追加(每次寫入前定位到末尾)
ios::ate打開後定位到末尾,但可隨意定位
ios::trunc截斷現有文件
ios::binary二進制模式(無換行轉換)

文本文件讀寫

ofstream fout("test.txt");
fout << "Hello\nWorld\n";
fout.close();

ifstream fin("test.txt");
string line;
while (getline(fin, line)) cout << line << '\n';

二進制文件讀寫

struct Student { char name[20]; int id; };
Student s1{"張三", 15}, s2;

ofstream bout("data.bin", ios::binary);
bout.write(reinterpret_cast(&s1), sizeof(s1));
bout.close();

ifstream bin("data.bin", ios::binary);
bin.read(reinterpret_cast(&s2), sizeof(s2));

流緩衝區直接操作

ifstream fin("big.txt");
cout << fin.rdbuf(); // 直接輸出整個文件緩衝區,極快

流定位

fstream f("test.txt", ios::in|ios::out);
f.seekg(0, ios::beg);   // 讀位置移到開頭
f.seekp(10, ios::cur);  // 寫位置從當前前移 10
f.seekg(-5, ios::end);  // 從末尾倒數 5 字節
// 單參數版本:seekg(pos) 絕對定位

字符串流(stringstream)

在內存 string 上進行格式化 I/O,無文件/控制台開銷。

#include 
using namespace std;

string text = "100 3.14 hello world";
istringstream sin(text);
int a; float b; string c, d;
sin >> a >> b >> c >> d; // 解析

ostringstream sout;
sout << a << ' ' << b << ' ' << c << ' ' << d;
string combined = sout.str(); // 獲取內容

// 雙向流
stringstream ss;
ss << "initial";
ss.seekg(0);
string restored;
ss >> restored;

最佳實踐清單

  1. 優先用 getline 讀文本行,避免 operator>> 留下換行符干擾後續讀取。
  2. 檢查流狀態 而非假設成功,if (fin) 隱式調用 good()。
  3. 二進制讀寫用 read/write + reinterpret_cast,注意結構體對齊與跨平台端序。
  4. 大文件複製用 rdbuf() 直接操作緩衝區,避免逐字符/逐行開銷。
  5. 字符串解析/構建用 stringstream,替代 sprintf/sscanf 類型安全。
  6. RAII 管理流對象:局部變量自動 close(),異常安全。

精通流庫,讓數據在程序、文件、內存、網絡間流動自如。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved