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

C++ 輸入輸出流 (iostream) 完整指南:從基礎到文件操作

     編輯:C++ 入門

核心架構

C++ IO 流體系以 streambuf 為底層緩衝區抽象,ios_base 管理格式狀態,basic_ios 提供狀態查詢,basic_istream/ostream/iostream 實現輸入/輸出操作,basic_stringstream/filebuffer 提供具體來源/目標。

運算符重載與鏈式調用


// ostream& operator<<(int val); 返回 *this 支援鏈式
std::cout << "Value: " << 42 << " Hex: " << std::hex << 42 << std::endl;
// 等價於:
std::operator<<(std::operator<<(std::cout, "Value: "), 42) ...;

返回引用而非值,避免拷貝並保持同一流對象身份。

指針與陣列輸出行為


char arr[] = "hello";
char* ptr = arr;
std::cout << arr;  // 輸出 "hello" (const char* 重載視為 C 風格字符串)
std::cout << ptr;  // 輸出 "hello"
std::cout << &arr; // 輸出地址 (const char(*)[6] 匹配 void* 重載)
std::cout << (void*)ptr; // 顯式輸出地址

int nums[] = {1,2,3};
std::cout << nums; // 輸出地址!無 int* 字符串重載,匹配 void*

關鍵規則:只有 char*/const char*/signed char*/unsigned char* 被視為 C 字符串輸出,其他指針均輸出地址。

無格式輸入操作

函數行為典型用法
get()讀取單字符,含換行/空白,EOF 返回 Traits::eof()char ch; while(cin.get(ch)) process(ch);
get(ch)讀取到參數引用,成功返回 *this,失敗設 failbitchar ch; while(cin.get(ch)) { ... }
get(buf, n, delim)讀最多 n-1 字符至緩衝區,遇 delim 停留流中cin.get(buf, 100, '\n');
getline(buf, n, delim)同上但提取並丟棄 delimcin.getline(buf, 100);
read(buf, n)讀取固定 n 字節(二進制),不足設 failbit|eofbitcin.read(buf, sizeof(header));
ignore(n, delim)跳過最多 n 字符,遇 delim 停止並提取cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
peek()查看下一字符不提取if (cin.peek() == '#') skipComment();
putback(ch)將字符放回流(僅保證 1 字符)cin.putback(ch);

格式化控制


// 基數
std::cout << std::hex << 255 << ' ' << std::oct << 255 << ' ' << std::dec << 255; // ff 377 255
// 浮點精度
std::cout << std::fixed << std::setprecision(2) << 3.14159; // 3.14
std::cout << std::scientific << std::setprecision(3) << 1234.5; // 1.235e+03
// 寬度、填充、對齊
std::cout << std::setw(10) << std::setfill('*') << std::left << "text"; // text******
// 布爾值輸出 true/false
std::cout << std::boolalpha << true << ' ' << false; // true false
// 顯示正號、大寫十六進制
std::cout << std::showpos << std::uppercase << std::hex << 255; // +FF

流狀態與錯誤處理


// 狀態位
std::ios::goodbit  // 0,一切正常
std::ios::eofbit   // 到達文件末尾
std::ios::failbit  // 邏輯錯誤(如格式不匹配)
std::ios::badbit   // 系統級錯誤(硬件故障)

// 檢查方法
if (cin) { ... }           // good()
if (!cin) { ... }          // fail() || bad()
if (cin.eof()) { ... }     // 專檢 EOF
if (cin.fail()) { ... }    // failbit 或 badbit
if (cin.bad()) { ... }     // 僅 badbit

// 恢復
cin.clear();               // 清除所有錯誤位
cin.clear(ios::goodbit);   // 同明確
cin.setstate(ios::failbit); // 手動設錯誤位

// 同步緩衝區 (C++11 廢棄 sync_with_stdio 相關)
cin.sync(); // 嘗試同步輸入緩衝區與外部設備,行為實現定義

文件流操作


#include <fstream>

// 輸出文件流
std::ofstream ofs("data.txt", std::ios::out | std::ios::trunc);
ofs << "Line 1\n" << 42 << ' ' << 3.14 << std::endl;
ofs.close(); // RAII 析構自動關閉

// 輸入文件流
std::ifstream ifs("data.txt");
std::string line;
while (std::getline(ifs, line)) {
    std::cout << line << '\n';
}

// 二進制讀寫
struct Header { int id; double timestamp; };
Header h{1, 1234567890.123};
std::ofstream bin("data.bin", std::ios::binary);
bin.write(reinterpret_cast<const char*>(&h), sizeof(h));
bin.close();

std::ifstream binIn("data.bin", std::ios::binary);
Header h2;
binIn.read(reinterpret_cast<char*>(&h2), sizeof(h2));

多文件處理與命令行參數


int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << "  [file2...]\n";
        return 1;
    }
    for (int i = 1; i < argc; ++i) {
        std::ifstream fin(argv[i]);
        if (!fin) {
            std::cerr << "Cannot open: " << argv[i] << '\n';
            continue; // 或 return
        }
        std::cout << "=== " << argv[i] << " ===\n";
        std::string line;
        while (std::getline(fin, line)) std::cout << line << '\n';
        fin.close();
        fin.clear(); // 清除狀態供下次復用(若復用同一流對象)
    }
}

進階主題

自定義類型流運算符


class Point { int x_, y_; 
public:
    friend std::ostream& operator<<(std::ostream& os, const Point& p) {
        return os << '(' << p.x_ << ", " << p.y_ << ')';
    }
    friend std::istream& operator>>(std::istream& is, Point& p) {
        char c; return is >> c >> p.x_ >> c >> p.y_ >> c; // 解析 (x, y)
    }
};

自定義 Manipulator


std::ostream& timestamp(std::ostream& os) {
    auto now = std::chrono::system_clock::now();
    auto t = std::chrono::system_clock::to_time_t(now);
    return os << '[' << std::put_time(std::localtime(&t), "%F %T") << "] ";
}
// 使用
std::cout << timestamp << "Log message\n"; // [2024-01-15 14:30:00] Log message

性能優化關鍵

  • std::ios::sync_with_stdio(false); std::cin.tie(nullptr); 關閉 C/C++ 流同步與 cin/cout 綁定,大幅提速。
  • 大量輸出用 ostringstream 累積一次性 flush,或直接寫入文件流。
  • 二進制大塊讀寫用 read/write 避免格式化開銷。
  • 避免頻繁 std::endl(隱含 flush),改用 '\n'。

總結

C++ IO 流雖語法豐富、類型安全、可擴展,但需注意:

  1. 區分格式化/無格式操作,選擇合適 API。
  2. 理解流狀態機制,正確處理錯誤與 EOF。
  3. 文件操作優先 RAII,二進制模式處理非文本數據。
  4. 性能敏感場景關閉同步、減少 flush、使用緩衝累積。
  5. 現代 C++ 結合 <format> (C++20)、<filesystem>、span 進一步簡化代碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved