最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ IO流詳解之標(biāo)準(zhǔn)IO、文件IO與字符串IO實(shí)戰(zhàn)

 更新時(shí)間:2026年03月11日 09:09:25   作者:星河耀銀海  
本文詳細(xì)介紹了C++中的IO流,包括標(biāo)準(zhǔn)IO流、文件IO流和字符串IO流,文章介紹了如何重載運(yùn)算符以支持自定義類型的IO流操作,并提供了一些實(shí)戰(zhàn)案例來說明如何使用IO流解決實(shí)際問題,感興趣的朋友跟隨小編一起看看吧

一、學(xué)習(xí)目標(biāo)與重點(diǎn)

  • 掌握C++ IO流的核心概念、體系結(jié)構(gòu)及基本工作原理
  • 熟練使用標(biāo)準(zhǔn)IO流(cin、cout、cerr、clog)進(jìn)行控制臺(tái)輸入輸出,掌握格式控制技巧
  • 精通文件IO流(ifstream、ofstream、fstream)的文件讀寫操作,處理常見文件場(chǎng)景
  • 學(xué)會(huì)使用字符串IO流(istringstream、ostringstream)進(jìn)行內(nèi)存數(shù)據(jù)的格式化與解析
  • 理解IO流的狀態(tài)標(biāo)志、錯(cuò)誤處理及緩沖區(qū)機(jī)制
  • 結(jié)合實(shí)戰(zhàn)案例,解決實(shí)際開發(fā)中的IO流應(yīng)用問題(如配置文件讀寫、數(shù)據(jù)序列化)

?? 核心重點(diǎn):IO流類體系的繼承關(guān)系、文件IO的打開模式與權(quán)限控制、格式控制符的靈活運(yùn)用、字符串IO的數(shù)據(jù)解析技巧

二、C++ IO流概述

2.1 什么是IO流

IO(Input/Output)流是C++中處理輸入輸出的核心機(jī)制,核心思想是“將數(shù)據(jù)的傳輸抽象為流”——數(shù)據(jù)從源端(如鍵盤、文件、內(nèi)存)流向目標(biāo)端(如屏幕、文件、內(nèi)存)的過程,稱為“流”。

??? 生活中的IO流類比:

  • 水流:水管中的水從水源(水庫)流向目的地(家庭),對(duì)應(yīng)數(shù)據(jù)從輸入源流向輸出目標(biāo)
  • 物流:快遞從商家(源)通過運(yùn)輸網(wǎng)絡(luò)(流)送達(dá)用戶(目標(biāo)),對(duì)應(yīng)數(shù)據(jù)的傳輸過程

C++ IO流的核心優(yōu)勢(shì):

  1. 統(tǒng)一的接口:無論是控制臺(tái)、文件還是內(nèi)存,均通過相同的流操作(如>>輸入、<<輸出)實(shí)現(xiàn),降低學(xué)習(xí)成本
  2. 靈活的格式控制:支持整數(shù)、浮點(diǎn)數(shù)、字符串等各種數(shù)據(jù)類型的格式化輸入輸出
  3. 可擴(kuò)展性:支持自定義類型的IO流操作(重載>><<運(yùn)算符)

2.2 C++ IO流類體系

C++標(biāo)準(zhǔn)庫通過一系列類實(shí)現(xiàn)IO流功能,這些類主要定義在<iostream>(標(biāo)準(zhǔn)IO)、<fstream>(文件IO)、<sstream>(字符串IO)頭文件中,核心類體系如下:

2.2.1 基類(抽象類)

  • ios_base:所有IO流類的頂層基類,定義了流的狀態(tài)標(biāo)志(如錯(cuò)誤、文件結(jié)束)、格式控制標(biāo)志(如左對(duì)齊、十六進(jìn)制)等
  • ios:繼承自ios_base,封裝了流的核心操作(如狀態(tài)檢查、緩沖區(qū)管理),是istreamostream的直接基類

2.2.2 核心流類

流類功能描述頭文件常用對(duì)象/實(shí)例化方式
istream輸入流基類,提供輸入操作(>>運(yùn)算符)<iostream>cin(標(biāo)準(zhǔn)輸入流,對(duì)應(yīng)鍵盤)
ostream輸出流基類,提供輸出操作(<<運(yùn)算符)<iostream>cout(標(biāo)準(zhǔn)輸出流,對(duì)應(yīng)屏幕)、cerr(標(biāo)準(zhǔn)錯(cuò)誤流)、clog(標(biāo)準(zhǔn)日志流)
iostream輸入輸出流類,繼承自istreamostream<iostream>用于雙向流操作(如文件讀寫)
ifstream文件輸入流類,繼承自istream<fstream>實(shí)例化對(duì)象讀取文件
ofstream文件輸出流類,繼承自ostream<fstream>實(shí)例化對(duì)象寫入文件
fstream文件輸入輸出流類,繼承自iostream<fstream>實(shí)例化對(duì)象讀寫文件
istringstream字符串輸入流類,繼承自istream<sstream>從字符串中讀取數(shù)據(jù)
ostringstream字符串輸出流類,繼承自ostream<sstream>向字符串中寫入數(shù)據(jù)(格式化)
stringstream字符串輸入輸出流類,繼承自iostream<sstream>對(duì)字符串進(jìn)行讀寫操作

?? 類體系核心關(guān)系:

ios_base ← ios ← istream ← ifstream / istringstream
ios_base ← ios ← ostream ← ofstream / ostringstream
istream + ostream ← iostream ← fstream / stringstream

2.3 IO流的狀態(tài)標(biāo)志

IO流的操作結(jié)果(成功、失敗、文件結(jié)束)通過“狀態(tài)標(biāo)志”標(biāo)識(shí),定義在ios_base中,核心狀態(tài)標(biāo)志如下:

狀態(tài)標(biāo)志描述檢查方法
goodbit流狀態(tài)正常(無錯(cuò)誤、未到文件結(jié)束)stream.good()
eofbit到達(dá)文件結(jié)束(如讀取文件到末尾)stream.eof()
failbit操作失?。ㄈ巛斎敕穷A(yù)期類型、文件打開失?。?/td>stream.fail()
badbit嚴(yán)重錯(cuò)誤(如內(nèi)存訪問錯(cuò)誤、文件損壞)stream.bad()

?? 狀態(tài)檢查與重置:

  • 流對(duì)象可直接作為布爾值判斷狀態(tài)(if (cin) 等價(jià)于 if (cin.good())
  • 重置狀態(tài)標(biāo)志:stream.clear()(清除所有狀態(tài)標(biāo)志,恢復(fù)為goodbit
  • 忽略錯(cuò)誤數(shù)據(jù):stream.ignore(n, ch)(忽略最多n個(gè)字符,或直到遇到字符ch)

?? 警告:流操作失敗后(如cin輸入非數(shù)字),流會(huì)設(shè)置failbit,后續(xù)所有IO操作都會(huì)被忽略,需調(diào)用clear()重置狀態(tài),并處理錯(cuò)誤數(shù)據(jù)。

三、標(biāo)準(zhǔn)IO流:控制臺(tái)輸入輸出

標(biāo)準(zhǔn)IO流是指與控制臺(tái)(鍵盤、屏幕)交互的流,核心對(duì)象包括cin(輸入)、cout(輸出)、cerr(錯(cuò)誤輸出)、clog(日志輸出),定義在<iostream>頭文件中。

3.1 標(biāo)準(zhǔn)輸出流:cout、cerr、clog

3.1.1 核心區(qū)別

  • cout:緩沖輸出流,數(shù)據(jù)先存入緩沖區(qū),緩沖區(qū)滿或遇到endl時(shí)才輸出到屏幕,效率較高
  • cerr:無緩沖輸出流,數(shù)據(jù)立即輸出到屏幕,用于輸出錯(cuò)誤信息(如程序異常)
  • clog:緩沖輸出流,與cout類似,但專門用于輸出日志信息(如操作記錄)

?? 示例:標(biāo)準(zhǔn)輸出流對(duì)比

#include <iostream>
using namespace std;
int main() {
    cout << "cout輸出:這是普通信息" << endl; // 換行并刷新緩沖區(qū)
    cerr << "cerr輸出:這是錯(cuò)誤信息" << endl; // 立即輸出,不受緩沖區(qū)影響
    clog << "clog輸出:這是日志信息" << endl; // 緩沖輸出,與cout類似
    // 測(cè)試緩沖區(qū):cout未刷新時(shí),數(shù)據(jù)可能延遲輸出
    cout << "cout無endl:"; 
    // 此時(shí)數(shù)據(jù)在緩沖區(qū),未輸出到屏幕
    cerr << "cerr插入:驗(yàn)證立即輸出" << endl; 
    // 輸出后,cout的緩沖區(qū)仍未刷新,直到程序結(jié)束或遇到endl
    return 0;
}

? 運(yùn)行結(jié)果:

cout輸出:這是普通信息
cerr輸出:這是錯(cuò)誤信息
clog輸出:這是日志信息
cerr插入:驗(yàn)證立即輸出
cout無endl:

3.1.2 格式控制

C++提供兩種格式控制方式:格式控制符(如setwhex)和成員函數(shù)(如setf、precision),需包含<<iomanip>頭文件(格式控制符專用)。

?? 常用格式控制(以cout為例):

#include <iostream>
#include <<iomanip> // 包含格式控制符
using namespace std;
int main() {
    int num = 255;
    double pi = 3.1415926535;
    string str = "C++ IO";
    // 1. 整數(shù)格式:十進(jìn)制、八進(jìn)制、十六進(jìn)制
    cout << "十進(jìn)制:" << dec << num << endl; // 255(默認(rèn))
    cout << "八進(jìn)制:" << oct << num << endl; // 377(前綴無0)
    cout << "十六進(jìn)制(小寫):" << hex << num << endl; // ff
    cout << "十六進(jìn)制(大寫):" << hex << uppercase << num << endl; // FF
    cout << resetiosflags(ios::uppercase); // 重置大寫格式
    // 2. 浮點(diǎn)數(shù)精度控制
    cout << "\n浮點(diǎn)數(shù)默認(rèn)精度(6位有效數(shù)字):" << pi << endl; // 3.14159
    cout << "保留2位小數(shù):" << fixed << setprecision(2) << pi << endl; // 3.14
    cout << "保留4位有效數(shù)字:" << resetiosflags(ios::fixed) << setprecision(4) << pi << endl; // 3.142
    // 3. 寬度與對(duì)齊
    cout << "\n左對(duì)齊(寬度10):" << left << setw(10) << str << "后續(xù)內(nèi)容" << endl; // "C++ IO     后續(xù)內(nèi)容"
    cout << "右對(duì)齊(寬度10):" << right << setw(10) << str << "后續(xù)內(nèi)容" << endl; // "     C++ IO后續(xù)內(nèi)容"
    cout << "填充字符(寬度10,填充*):" << setfill('*') << setw(10) << str << endl; // "*****C++ IO"
    // 4. 布爾值格式
    bool flag = true;
    cout << "\n布爾值默認(rèn):" << flag << endl; // 1
    cout << "布爾值文字(true/false):" << boolalpha << flag << endl; // true
    cout << resetiosflags(ios::boolalpha); // 重置布爾值格式
    return 0;
}

? 運(yùn)行結(jié)果:

十進(jìn)制:255
八進(jìn)制:377
十六進(jìn)制(小寫):ff
十六進(jìn)制(大寫):FF

浮點(diǎn)數(shù)默認(rèn)精度(6位有效數(shù)字):3.14159
保留2位小數(shù):3.14
保留4位有效數(shù)字:3.142

左對(duì)齊(寬度10):C++ IO     后續(xù)內(nèi)容
右對(duì)齊(寬度10):     C++ IO后續(xù)內(nèi)容
填充字符(寬度10,填充*):*****C++ IO

布爾值默認(rèn):1
布爾值文字(true/false):true

3.2 標(biāo)準(zhǔn)輸入流:cin

cinistream類的實(shí)例,用于從鍵盤讀取數(shù)據(jù),核心操作是>>運(yùn)算符(提取運(yùn)算符),支持各種基本數(shù)據(jù)類型的輸入。

3.2.1 基本輸入用法

#include <iostream>
#include <string>
using namespace std;
int main() {
    int a;
    double b;
    string s;
    cout << "請(qǐng)輸入一個(gè)整數(shù)、一個(gè)浮點(diǎn)數(shù)和一個(gè)字符串(空格分隔):";
    cin >> a >> b >> s; // 按順序讀取,空格/回車作為分隔符
    cout << "\n你輸入的整數(shù):" << a << endl;
    cout << "你輸入的浮點(diǎn)數(shù):" << b << endl;
    cout << "你輸入的字符串:" << s << endl;
    return 0;
}

? 運(yùn)行示例:

請(qǐng)輸入一個(gè)整數(shù)、一個(gè)浮點(diǎn)數(shù)和一個(gè)字符串(空格分隔):10 3.14 Hello
你輸入的整數(shù):10
你輸入的浮點(diǎn)數(shù):3.14
你輸入的字符串:Hello

3.2.2 常見問題與解決方案

問題1:輸入數(shù)據(jù)類型不匹配

當(dāng)輸入的數(shù)據(jù)類型與變量類型不一致時(shí)(如int變量輸入字符串),cin會(huì)設(shè)置failbit,后續(xù)輸入操作失效。

?? 解決方案:檢查狀態(tài)并重置

#include <iostream>
#include <limits> // 包含numeric_limits
using namespace std;
int main() {
    int num;
    cout << "請(qǐng)輸入一個(gè)整數(shù):";
    cin >> num;
    if (!cin) { // 等價(jià)于cin.fail(),輸入失敗
        cout << "輸入錯(cuò)誤!請(qǐng)輸入整數(shù)類型。" << endl;
        cin.clear(); // 重置狀態(tài)標(biāo)志
        // 忽略緩沖區(qū)中所有錯(cuò)誤數(shù)據(jù)(直到換行)
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    } else {
        cout << "你輸入的整數(shù):" << num << endl;
    }
    // 重新輸入
    cout << "請(qǐng)重新輸入一個(gè)整數(shù):";
    cin >> num;
    cout << "你重新輸入的整數(shù):" << num << endl;
    return 0;
}

問題2:讀取帶空格的字符串

>>運(yùn)算符默認(rèn)以空格、回車、制表符為分隔符,無法讀取帶空格的字符串(如“Hello World”)。

?? 解決方案:使用getline()函數(shù)

#include <iostream>
#include <string>
using namespace std;
int main() {
    string name;
    cout << "請(qǐng)輸入你的姓名(可帶空格):";
    // 注意:若之前有cin >> 操作,需先忽略緩沖區(qū)中的換行符
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    getline(cin, name); // 讀取整行數(shù)據(jù),包括空格
    cout << "你好," << name << "!" << endl;
    return 0;
}

?? 注意:cin >> 之后調(diào)用 getline() 時(shí),cin >> 會(huì)將換行符留在緩沖區(qū),getline() 會(huì)直接讀取空字符串,因此需先用 cin.ignore() 忽略換行符。

問題3:讀取指定長度的字符

使用cin.get(char* buf, int n)讀取最多n-1個(gè)字符(最后一個(gè)字符為’\0’),或直到遇到指定分隔符。

?? 示例:讀取指定長度的字符串

#include <iostream>
using namespace std;
int main() {
    char buf[10]; // 最多存儲(chǔ)9個(gè)字符+1個(gè)'\0'
    cout << "請(qǐng)輸入字符串(最多9個(gè)字符):";
    cin.get(buf, 10); // 讀取最多9個(gè)字符,遇到換行或滿9個(gè)字符停止
    cout << "你輸入的字符串:" << buf << endl;
    return 0;
}

四、文件IO流:文件讀寫操作

文件IO流用于與磁盤文件進(jìn)行交互,核心類是ifstream(讀文件)、ofstream(寫文件)、fstream(讀寫文件),需包含<fstream>頭文件。

4.1 文件打開與關(guān)閉

4.1.1 打開文件的兩種方式

  1. 構(gòu)造函數(shù)打開:實(shí)例化流對(duì)象時(shí),通過構(gòu)造函數(shù)指定文件名和打開模式
  2. open()方法打開:先實(shí)例化流對(duì)象,再調(diào)用open(const string& filename, ios::openmode mode)方法

4.1.2 核心打開模式(ios::openmode)

文件打開模式用于指定文件的操作類型(讀/寫)、文件存在時(shí)的處理方式(覆蓋/追加)等,可通過位或(|)組合使用:

打開模式描述適用類
ios::in讀模式(文件必須存在,否則打開失?。?/td>ifstream、fstream
ios::out寫模式(文件不存在則創(chuàng)建,存在則覆蓋)ofstream、fstream
ios::app追加模式(文件不存在則創(chuàng)建,寫入數(shù)據(jù)追加到文件末尾)ofstream、fstream
ios::trunc截?cái)嗄J剑ㄎ募嬖趧t清空內(nèi)容,默認(rèn)與ios::out結(jié)合)ofstream、fstream
ios::binary二進(jìn)制模式(默認(rèn)是文本模式)所有文件流類
ios::ate打開文件后定位到文件末尾所有文件流類

?? 常用模式組合:

  • 讀文本文件:ios::in(ifstream默認(rèn)模式)
  • 寫文本文件(覆蓋):ios::outios::out | ios::trunc(ofstream默認(rèn)模式)
  • 寫文本文件(追加):ios::out | ios::app
  • 讀寫文本文件:ios::in | ios::out
  • 讀二進(jìn)制文件:ios::in | ios::binary

4.1.3 文件關(guān)閉

文件使用完畢后,需調(diào)用close()方法關(guān)閉文件,釋放文件資源(如文件句柄)。即使不手動(dòng)調(diào)用close(),流對(duì)象析構(gòu)時(shí)也會(huì)自動(dòng)關(guān)閉文件,但建議手動(dòng)關(guān)閉(避免異常導(dǎo)致資源泄漏)。

?? 警告:打開文件后必須檢查是否打開成功,否則后續(xù)操作會(huì)失敗。

4.2 文本文件讀寫

文本文件存儲(chǔ)的是人類可讀的字符(如ASCII碼、UTF-8編碼),讀寫操作與標(biāo)準(zhǔn)IO流類似(使用>><<、getline())。

4.2.1 文本文件寫入(ofstream)

?? 示例:創(chuàng)建文本文件并寫入內(nèi)容

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    // 1. 構(gòu)造函數(shù)打開文件(寫模式,覆蓋原有內(nèi)容)
    ofstream out_file("test.txt", ios::out | ios::trunc);
    // 檢查文件是否打開成功
    if (!out_file.is_open()) {
        cerr << "文件打開失??!" << endl;
        return 1;
    }
    // 2. 寫入數(shù)據(jù)(使用<<運(yùn)算符)
    out_file << "Hello, File IO!" << endl;
    out_file << "這是C++文本文件寫入示例" << endl;
    out_file << "整數(shù):" << 100 << ",浮點(diǎn)數(shù):" << 3.14 << endl;
    // 3. 寫入字符串(使用write()方法,指定長度)
    string str = "使用write()方法寫入的內(nèi)容";
    out_file.write(str.c_str(), str.length());
    out_file << endl;
    // 4. 關(guān)閉文件
    out_file.close();
    cout << "文件寫入完成!" << endl;
    return 0;
}

? 運(yùn)行結(jié)果:生成test.txt文件,內(nèi)容如下:

Hello, File IO!
這是C++文本文件寫入示例
整數(shù):100,浮點(diǎn)數(shù):3.14
使用write()方法寫入的內(nèi)容

4.2.2 文本文件讀?。╥fstream)

文本文件讀取有三種常用方式:>>運(yùn)算符、getline()函數(shù)、read()方法。

?? 示例:讀取文本文件內(nèi)容

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    // 1. 打開文件(讀模式)
    ifstream in_file("test.txt", ios::in);
    if (!in_file.is_open()) {
        cerr << "文件打開失??!" << endl;
        return 1;
    }
    cout << "=== 方式1:使用>>運(yùn)算符讀取(忽略空格和換行) ===" << endl;
    string word;
    while (in_file >> word) { // 直到文件結(jié)束(eofbit)
        cout << word << " ";
    }
    cout << endl;
    // 重置文件指針到開頭(否則后續(xù)讀取會(huì)從文件末尾開始)
    in_file.clear(); // 重置狀態(tài)標(biāo)志(因eofbit已設(shè)置)
    in_file.seekg(0, ios::beg); // 移動(dòng)文件指針到開頭(ios::beg=文件開頭)
    cout << "\n=== 方式2:使用getline()讀取整行 ===" << endl;
    string line;
    while (getline(in_file, line)) { // 逐行讀取
        cout << line << endl;
    }
    in_file.clear();
    in_file.seekg(0, ios::beg);
    cout << "\n=== 方式3:使用read()讀取指定字節(jié)數(shù) ===" << endl;
    char buf[1024];
    in_file.read(buf, sizeof(buf)); // 讀取最多1023個(gè)字符
    buf[in_file.gcount()] = '\0'; // gcount()返回實(shí)際讀取的字節(jié)數(shù),添加字符串結(jié)束符
    cout << buf << endl;
    // 關(guān)閉文件
    in_file.close();
    cout << "\n文件讀取完成!" << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

=== 方式1:使用>>運(yùn)算符讀?。ê雎钥崭窈蛽Q行) ===
Hello, File IO! 這是C++文本文件寫入示例 整數(shù):100,浮點(diǎn)數(shù):3.14 使用write()方法寫入的內(nèi)容 
=== 方式2:使用getline()讀取整行 ===
Hello, File IO!
這是C++文本文件寫入示例
整數(shù):100,浮點(diǎn)數(shù):3.14
使用write()方法寫入的內(nèi)容
=== 方式3:使用read()讀取指定字節(jié)數(shù) ===
Hello, File IO!
這是C++文本文件寫入示例
整數(shù):100,浮點(diǎn)數(shù):3.14
使用write()方法寫入的內(nèi)容
文件讀取完成!

4.3 二進(jìn)制文件讀寫

二進(jìn)制文件存儲(chǔ)的是字節(jié)流(如圖片、視頻、可執(zhí)行文件),讀寫時(shí)需指定ios::binary模式,使用read()write()方法(按字節(jié)操作)。

4.3.1 二進(jìn)制文件寫入

?? 示例:將結(jié)構(gòu)體數(shù)據(jù)寫入二進(jìn)制文件

#include <iostream>
#include <fstream>
using namespace std;
// 定義結(jié)構(gòu)體(存儲(chǔ)用戶信息)
struct User {
    char name[20]; // 用戶名
    int age;       // 年齡
    double score;  // 分?jǐn)?shù)
};
int main() {
    // 1. 打開二進(jìn)制文件(寫模式)
    ofstream out_file("users.bin", ios::out | ios::binary | ios::trunc);
    if (!out_file.is_open()) {
        cerr << "文件打開失?。? << endl;
        return 1;
    }
    // 2. 準(zhǔn)備數(shù)據(jù)
    User user1 = {"張三", 20, 95.5};
    User user2 = {"李四", 22, 88.0};
    // 3. 寫入數(shù)據(jù)(write()參數(shù):數(shù)據(jù)地址、字節(jié)數(shù))
    out_file.write(reinterpret_cast<const char*>(&user1), sizeof(User));
    out_file.write(reinterpret_cast<const char*>(&user2), sizeof(User));
    // 4. 關(guān)閉文件
    out_file.close();
    cout << "二進(jìn)制文件寫入完成!" << endl;
    return 0;
}

4.3.2 二進(jìn)制文件讀取

?? 示例:從二進(jìn)制文件讀取結(jié)構(gòu)體數(shù)據(jù)

#include <iostream>
#include <fstream>
using namespace std;
struct User {
    char name[20];
    int age;
    double score;
};
int main() {
    // 1. 打開二進(jìn)制文件(讀模式)
    ifstream in_file("users.bin", ios::in | ios::binary);
    if (!in_file.is_open()) {
        cerr << "文件打開失??!" << endl;
        return 1;
    }
    // 2. 讀取數(shù)據(jù)
    User user;
    cout << "=== 讀取二進(jìn)制文件內(nèi)容 ===" << endl;
    // 循環(huán)讀取,直到文件結(jié)束
    while (in_file.read(reinterpret_cast<char*>(&user), sizeof(User))) {
        cout << "用戶名:" << user.name 
             << ",年齡:" << user.age 
             << ",分?jǐn)?shù):" << user.score << endl;
    }
    // 檢查讀取是否因文件結(jié)束而停止
    if (in_file.eof()) {
        cout << "讀取完成(已到文件末尾)" << endl;
    } else if (in_file.fail()) {
        cerr << "讀取失??!" << endl;
    }
    // 3. 關(guān)閉文件
    in_file.close();
    return 0;
}

? 運(yùn)行結(jié)果:

=== 讀取二進(jìn)制文件內(nèi)容 ===
用戶名:張三,年齡:20,分?jǐn)?shù):95.5
用戶名:李四,年齡:22,分?jǐn)?shù):88
讀取完成(已到文件末尾)

?? 注意事項(xiàng):

  • 二進(jìn)制文件讀寫需確保數(shù)據(jù)類型的大小和內(nèi)存布局一致(如32位系統(tǒng)與64位系統(tǒng)的int大小可能不同)
  • 結(jié)構(gòu)體中若包含指針(如char* name),寫入的是指針地址而非實(shí)際數(shù)據(jù),讀取后指針可能失效(懸空指針)

4.4 文件指針操作

文件指針用于定位文件中的讀寫位置,分為輸入指針(gptr,用于讀操作)和輸出指針(pptr,用于寫操作),通過以下成員函數(shù)操作:

函數(shù)名功能描述參數(shù)說明
seekg(pos, mode)移動(dòng)輸入指針到指定位置pos:偏移量;mode:基準(zhǔn)位置(ios::beg=開頭、ios::cur=當(dāng)前、ios::end=末尾)
seekp(pos, mode)移動(dòng)輸出指針到指定位置同seekg
tellg()獲取輸入指針當(dāng)前位置(相對(duì)于文件開頭的字節(jié)數(shù))返回值:streampos類型(可轉(zhuǎn)換為int)
tellp()獲取輸出指針當(dāng)前位置同tellg

?? 示例:文件指針操作(讀取文件中間內(nèi)容)

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
    ifstream in_file("test.txt", ios::in);
    if (!in_file.is_open()) {
        cerr << "文件打開失?。? << endl;
        return 1;
    }
    // 1. 獲取文件大?。ㄒ苿?dòng)指針到末尾,獲取位置)
    in_file.seekg(0, ios::end);
    int file_size = in_file.tellg();
    cout << "文件大?。? << file_size << "字節(jié)" << endl;
    // 2. 移動(dòng)指針到文件中間(第20字節(jié)處)
    in_file.seekg(20, ios::beg);
    cout << "指針位置(第20字節(jié)):" << in_file.tellg() << endl;
    // 3. 讀取從第20字節(jié)開始的內(nèi)容
    string content;
    getline(in_file, content);
    cout << "從第20字節(jié)開始的內(nèi)容:" << content << endl;
    in_file.close();
    return 0;
}

? 運(yùn)行結(jié)果(假設(shè)test.txt第20字節(jié)后內(nèi)容為“這是C++文本文件寫入示例”):

文件大?。?5字節(jié)
指針位置(第20字節(jié)):20
從第20字節(jié)開始的內(nèi)容:這是C++文本文件寫入示例

五、字符串IO流:內(nèi)存數(shù)據(jù)格式化與解析

字符串IO流用于在內(nèi)存中對(duì)字符串進(jìn)行格式化輸入輸出,核心類是istringstream(從字符串讀)、ostringstream(向字符串寫)、stringstream(讀寫字符串),需包含<sstream>頭文件。

字符串IO流的核心應(yīng)用場(chǎng)景:

  1. 數(shù)據(jù)格式化:將多個(gè)基本類型數(shù)據(jù)拼接為字符串(如日志記錄)
  2. 數(shù)據(jù)解析:將字符串按指定格式拆分為多個(gè)基本類型數(shù)據(jù)(如解析配置文件、網(wǎng)絡(luò)數(shù)據(jù))

5.1 ostringstream:字符串格式化輸出

ostringstream用于將各種類型數(shù)據(jù)寫入字符串(內(nèi)存緩沖區(qū)),支持格式控制,最終通過str()方法獲取格式化后的字符串。

?? 示例:格式化日志字符串

#include <iostream>
#include <sstream>
#include <<iomanip>
#include <string>
using namespace std;
int main() {
    // 1. 創(chuàng)建ostringstream對(duì)象
    ostringstream oss;
    // 2. 格式化寫入數(shù)據(jù)(支持格式控制)
    string level = "INFO";
    string module = "FileHandler";
    int line = 100;
    double cost = 0.023;
    oss << "[" << level << "] "
        << "模塊:" << module << ","
        << "行號(hào):" << line << ","
        << "耗時(shí):" << fixed << setprecision(4) << cost << "秒";
    // 3. 獲取格式化后的字符串
    string log = oss.str();
    cout << "格式化日志:" << log << endl;
    // 4. 追加內(nèi)容
    oss << ",狀態(tài):成功";
    cout << "追加后日志:" << oss.str() << endl;
    // 5. 清空緩沖區(qū)(重新使用)
    oss.str(""); // 清空字符串內(nèi)容
    oss.clear(); // 重置狀態(tài)標(biāo)志
    oss << "[" << "ERROR" << "] " << "文件打開失敗,路徑:test.txt";
    cout << "新日志:" << oss.str() << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

格式化日志:[INFO] 模塊:FileHandler,行號(hào):100,耗時(shí):0.0230秒
追加后日志:[INFO] 模塊:FileHandler,行號(hào):100,耗時(shí):0.0230秒,狀態(tài):成功
新日志:[ERROR] 文件打開失敗,路徑:test.txt

5.2 istringstream:字符串解析輸入

istringstream用于從字符串中讀取數(shù)據(jù),按指定格式拆分字符串為多個(gè)基本類型數(shù)據(jù),支持>>運(yùn)算符和getline()函數(shù)。

?? 示例1:解析空格分隔的字符串

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
    string data = "10 3.14 Hello C++";
    istringstream iss(data);
    // 解析數(shù)據(jù)
    int num;
    double pi;
    string str1, str2;
    iss >> num >> pi >> str1 >> str2;
    cout << "解析結(jié)果:" << endl;
    cout << "整數(shù):" << num << endl;
    cout << "浮點(diǎn)數(shù):" << pi << endl;
    cout << "字符串1:" << str1 << endl;
    cout << "字符串2:" << str2 << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

解析結(jié)果:
整數(shù):10
浮點(diǎn)數(shù):3.14
字符串1:Hello
字符串2:C++

?? 示例2:解析逗號(hào)分隔的配置字符串(如CSV數(shù)據(jù))

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
    // 模擬CSV格式的配置數(shù)據(jù):姓名,年齡,分?jǐn)?shù)
    string config = "張三,20,95.5";
    istringstream iss(config);
    string field;
    // 按逗號(hào)分隔解析
    getline(iss, field, ','); // 讀取第一個(gè)字段(姓名)
    string name = field;
    getline(iss, field, ','); // 讀取第二個(gè)字段(年齡)
    int age = stoi(field); // 字符串轉(zhuǎn)整數(shù)
    getline(iss, field, ','); // 讀取第三個(gè)字段(分?jǐn)?shù))
    double score = stod(field); // 字符串轉(zhuǎn)浮點(diǎn)數(shù)
    cout << "配置解析結(jié)果:" << endl;
    cout << "姓名:" << name << endl;
    cout << "年齡:" << age << endl;
    cout << "分?jǐn)?shù):" << score << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

配置解析結(jié)果:
姓名:張三
年齡:20
分?jǐn)?shù):95.5

5.3 stringstream:字符串讀寫雙向操作

stringstream兼具istringstreamostringstream的功能,可對(duì)字符串進(jìn)行讀寫操作,適用于需要先格式化再解析的場(chǎng)景。

?? 示例:字符串讀寫雙向操作

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
    stringstream ss;
    // 1. 寫入數(shù)據(jù)(格式化)
    ss << "姓名:" << "李四" << ",年齡:" << 22 << ",分?jǐn)?shù):" << 88.0;
    cout << "格式化字符串:" << ss.str() << endl;
    // 2. 讀取解析(忽略非數(shù)字字符,提取年齡和分?jǐn)?shù))
    ss.clear(); // 重置狀態(tài)標(biāo)志
    ss.seekg(0, ios::beg); // 移動(dòng)指針到開頭
    string temp;
    int age;
    double score;
    // 跳過"姓名:李四,年齡:"等非數(shù)字內(nèi)容
    while (ss >> temp) {
        if (temp == "年齡:") {
            ss >> age; // 提取年齡
        } else if (temp == "分?jǐn)?shù):") {
            ss >> score; // 提取分?jǐn)?shù)
        }
    }
    cout << "解析結(jié)果:" << endl;
    cout << "年齡:" << age << endl;
    cout << "分?jǐn)?shù):" << score << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

格式化字符串:姓名:李四,年齡:22,分?jǐn)?shù):88
解析結(jié)果:
年齡:22
分?jǐn)?shù):88

六、IO流的高級(jí)應(yīng)用:自定義類型的IO流

C++支持為自定義類型(如類、結(jié)構(gòu)體)重載>>(輸入)和<<(輸出)運(yùn)算符,使自定義類型可以像基本類型一樣使用IO流操作。

6.1 重載<<運(yùn)算符(輸出)

重載<<運(yùn)算符需定義為全局函數(shù)(或類的友元函數(shù)),參數(shù)為ostream&和自定義類型的引用,返回ostream&(支持鏈?zhǔn)秸{(diào)用)。

6.2 重載>>運(yùn)算符(輸入)

重載>>運(yùn)算符同樣定義為全局函數(shù),參數(shù)為istream&和自定義類型的引用,返回istream&。

?? 示例:自定義Person類的IO流重載

#include <iostream>
#include <string>
#include <<iomanip>
using namespace std;
class Person {
private:
    string name;
    int age;
    double height;
public:
    // 構(gòu)造函數(shù)
    Person(string n = "", int a = 0, double h = 0.0) 
        : name(n), age(a), height(h) {}
    // 友元函數(shù):重載<<運(yùn)算符(輸出)
    friend ostream& operator<<(ostream& os, const Person& p);
    // 友元函數(shù):重載>>運(yùn)算符(輸入)
    friend istream& operator>>(istream& is, Person& p);
};
// 重載<<運(yùn)算符:輸出Person對(duì)象
ostream& operator<<(ostream& os, const Person& p) {
    os << "姓名:" << setw(8) << left << p.name
       << ",年齡:" << setw(3) << p.age
       << ",身高:" << fixed << setprecision(2) << p.height << "m";
    return os; // 支持鏈?zhǔn)秸{(diào)用(如cout << p1 << p2)
}
// 重載>>運(yùn)算符:輸入Person對(duì)象
istream& operator>>(istream& is, Person& p) {
    cout << "請(qǐng)輸入姓名、年齡、身高(空格分隔):";
    is >> p.name >> p.age >> p.height;
    // 可選:輸入驗(yàn)證
    if (p.age < 0 || p.age > 150) {
        is.setstate(ios::failbit); // 設(shè)置失敗狀態(tài)
        cerr << "輸入錯(cuò)誤:年齡非法!" << endl;
    }
    return is;
}
int main() {
    Person p1("張三", 20, 1.75);
    Person p2;
    // 輸出自定義類型(使用重載的<<)
    cout << "p1信息:" << p1 << endl;
    // 輸入自定義類型(使用重載的>>)
    if (cin >> p2) {
        cout << "p2信息:" << p2 << endl;
    }
    // 鏈?zhǔn)捷敵?
    Person p3("李四", 22, 1.80);
    cout << "\n鏈?zhǔn)捷敵觯? << p1 << " | " << p3 << endl;
    return 0;
}

? 運(yùn)行結(jié)果:

p1信息:姓名:張三      ,年齡: 20,身高:1.75m
請(qǐng)輸入姓名、年齡、身高(空格分隔):王五 25 1.85
p2信息:姓名:王五      ,年齡: 25,身高:1.85m

鏈?zhǔn)捷敵觯盒彰簭埲?     ,年齡: 20,身高:1.75m | 姓名:李四      ,年齡: 22,身高:1.80m

七、IO流的常見錯(cuò)誤與最佳實(shí)踐

7.1 常見錯(cuò)誤

錯(cuò)誤1:文件打開失敗未檢查

未檢查文件是否打開成功,直接進(jìn)行讀寫操作,導(dǎo)致程序崩潰或產(chǎn)生無效數(shù)據(jù)。

錯(cuò)誤2:流狀態(tài)異常未處理

cin輸入類型不匹配、文件讀取到末尾后繼續(xù)讀取,未重置流狀態(tài),導(dǎo)致后續(xù)IO操作失效。

錯(cuò)誤3:二進(jìn)制文件與文本文件模式混用

用文本模式讀取二進(jìn)制文件(如圖片、視頻),會(huì)導(dǎo)致數(shù)據(jù)解析錯(cuò)誤(如換行符轉(zhuǎn)換)。

錯(cuò)誤4:字符串IO流未清空狀態(tài)

重復(fù)使用stringstream時(shí),未調(diào)用clear()重置狀態(tài)標(biāo)志,導(dǎo)致后續(xù)讀取失敗。

錯(cuò)誤5:自定義類型IO流重載錯(cuò)誤

重載<<>>時(shí)未返回ostream&istream&,導(dǎo)致鏈?zhǔn)秸{(diào)用失效。

7.2 最佳實(shí)踐

實(shí)踐1:始終檢查文件打開狀態(tài)

打開文件后,通過is_open()或流對(duì)象的布爾值判斷是否打開成功。

實(shí)踐2:及時(shí)處理流狀態(tài)異常

IO操作后檢查流狀態(tài)(如if (!cin)),失敗時(shí)調(diào)用clear()重置狀態(tài),并處理錯(cuò)誤數(shù)據(jù)。

實(shí)踐3:明確文件操作模式

  • 文本文件:默認(rèn)模式(不指定ios::binary),使用>>、<<、getline()操作
  • 二進(jìn)制文件:必須指定ios::binary模式,使用read()、write()操作

實(shí)踐4:合理使用緩沖區(qū)

  • 標(biāo)準(zhǔn)輸出流cout:使用endl刷新緩沖區(qū),或flush()手動(dòng)刷新
  • 文件流:大文件讀寫時(shí),可通過pubsetbuf()設(shè)置更大的緩沖區(qū),提升效率

實(shí)踐5:資源管理

  • 文件流:使用完畢后手動(dòng)調(diào)用close()關(guān)閉文件,或利用RAII(如將文件流封裝在類中,析構(gòu)時(shí)關(guān)閉)
  • 字符串流:不需要手動(dòng)關(guān)閉,析構(gòu)時(shí)自動(dòng)釋放內(nèi)存

實(shí)踐6:格式化輸出優(yōu)先使用ostringstream

拼接復(fù)雜字符串(如日志、配置)時(shí),優(yōu)先使用ostringstream,避免多次string拼接(效率低)。

八、實(shí)戰(zhàn)案例:配置文件讀寫工具

8.1 問題描述

實(shí)現(xiàn)一個(gè)配置文件讀寫工具,支持:

  1. 讀取INI格式的配置文件(鍵值對(duì)形式,如name=張三
  2. 解析配置項(xiàng)為字符串、整數(shù)、浮點(diǎn)數(shù)類型
  3. 修改配置項(xiàng)并寫入文件(覆蓋原有內(nèi)容)
  4. 處理配置文件不存在、格式錯(cuò)誤等異常場(chǎng)景

8.2 實(shí)現(xiàn)思路

  1. 定義ConfigReader類,封裝配置文件的讀取、解析、寫入操作
  2. 使用map<string, string>存儲(chǔ)配置項(xiàng)(鍵-值對(duì))
  3. 讀取配置文件:使用ifstream讀取文件,istringstream解析每行的鍵值對(duì)
  4. 寫入配置文件:使用ofstreammap中的鍵值對(duì)寫入文件
  5. 提供getString()、getInt()、getDouble()方法獲取不同類型的配置值
  6. 提供setConfig()方法修改配置項(xiàng)

8.3 代碼實(shí)現(xiàn)

#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <string>
#include <stdexcept> // 包含異常類
using namespace std;
class ConfigReader {
private:
    string filename; // 配置文件名
    map<string, string> config_map; // 存儲(chǔ)鍵值對(duì)
public:
    // 構(gòu)造函數(shù):指定配置文件名并讀取配置
    ConfigReader(const string& fname) : filename(fname) {
        readConfig();
    }
    // 讀取配置文件
    void readConfig() {
        ifstream in_file(filename, ios::in);
        if (!in_file.is_open()) {
            // 配置文件不存在,創(chuàng)建空配置(不拋出異常,允許后續(xù)寫入)
            cout << "配置文件" << filename << "不存在,將創(chuàng)建新文件" << endl;
            return;
        }
        string line;
        int line_num = 0;
        while (getline(in_file, line)) {
            line_num++;
            // 跳過空行和注釋行(以#開頭)
            if (line.empty() || line[0] == '#') {
                continue;
            }
            // 解析鍵值對(duì)(格式:key=value)
            size_t eq_pos = line.find('=');
            if (eq_pos == string::npos) {
                cerr << "警告:第" << line_num << "行格式錯(cuò)誤(無=),跳過該行" << endl;
                continue;
            }
            string key = line.substr(0, eq_pos);
            string value = line.substr(eq_pos + 1);
            // 去除鍵和值的前后空格
            key = trim(key);
            value = trim(value);
            if (!key.empty()) {
                config_map[key] = value;
            }
        }
        in_file.close();
        cout << "配置文件讀取完成,共" << config_map.size() << "個(gè)配置項(xiàng)" << endl;
    }
    // 寫入配置文件(覆蓋原有內(nèi)容)
    void writeConfig() {
        ofstream out_file(filename, ios::out | ios::trunc);
        if (!out_file.is_open()) {
            throw runtime_error("配置文件" + filename + "寫入失?。?quán)限不足或路徑錯(cuò)誤)");
        }
        // 寫入注釋
        out_file << "# 配置文件:" << filename << endl;
        out_file << "# 格式:key=value(#開頭為注釋,空行忽略)" << endl << endl;
        // 寫入鍵值對(duì)
        for (const auto& pair : config_map) {
            out_file << pair.first << "=" << pair.second << endl;
        }
        out_file.close();
        cout << "配置文件寫入完成!" << endl;
    }
    // 獲取字符串類型配置
    string getString(const string& key, const string& default_val = "") const {
        auto it = config_map.find(key);
        return (it != config_map.end()) ? it->second : default_val;
    }
    // 獲取整數(shù)類型配置
    int getInt(const string& key, int default_val = 0) const {
        auto it = config_map.find(key);
        if (it == config_map.end()) {
            return default_val;
        }
        // 字符串轉(zhuǎn)整數(shù)
        istringstream iss(it->second);
        int val;
        if (!(iss >> val)) {
            cerr << "警告:配置項(xiàng)" << key << "的值" << it->second << "不是整數(shù),返回默認(rèn)值" << default_val << endl;
            return default_val;
        }
        return val;
    }
    // 獲取浮點(diǎn)數(shù)類型配置
    double getDouble(const string& key, double default_val = 0.0) const {
        auto it = config_map.find(key);
        if (it == config_map.end()) {
            return default_val;
        }
        istringstream iss(it->second);
        double val;
        if (!(iss >> val)) {
            cerr << "警告:配置項(xiàng)" << key << "的值" << it->second << "不是浮點(diǎn)數(shù),返回默認(rèn)值" << default_val << endl;
            return default_val;
        }
        return val;
    }
    // 修改配置項(xiàng)
    void setConfig(const string& key, const string& value) {
        config_map[key] = value;
    }
private:
    // 輔助函數(shù):去除字符串前后空格
    string trim(const string& str) {
        size_t start = str.find_first_not_of(" \t\n\r");
        size_t end = str.find_last_not_of(" \t\n\r");
        return (start == string::npos || end == string::npos) ? "" : str.substr(start, end - start + 1);
    }
};
int main() {
    try {
        // 1. 創(chuàng)建配置讀取器(讀取config.ini)
        ConfigReader config("config.ini");
        // 2. 獲取配置項(xiàng)(帶默認(rèn)值)
        cout << "\n=== 讀取配置項(xiàng) ===" << endl;
        string name = config.getString("name", "未知");
        int age = config.getInt("age", 18);
        double score = config.getDouble("score", 60.0);
        string address = config.getString("address", "未設(shè)置");
        cout << "姓名:" << name << endl;
        cout << "年齡:" << age << endl;
        cout << "分?jǐn)?shù):" << score << endl;
        cout << "地址:" << address << endl;
        // 3. 修改配置項(xiàng)
        cout << "\n=== 修改配置項(xiàng) ===" << endl;
        config.setConfig("name", "李四");
        config.setConfig("age", "22");
        config.setConfig("score", "95.5");
        config.setConfig("address", "北京市");
        // 4. 寫入配置文件
        config.writeConfig();
        // 5. 重新讀取驗(yàn)證
        cout << "\n=== 重新讀取配置項(xiàng) ===" << endl;
        config.readConfig(); // 重新讀取文件
        cout << "姓名:" << config.getString("name") << endl;
        cout << "年齡:" << config.getInt("age") << endl;
        cout << "地址:" << config.getString("address") << endl;
    } catch (const exception& e) {
        cerr << "錯(cuò)誤:" << e.what() << endl;
        return 1;
    }
    return 0;
}

8.4 運(yùn)行結(jié)果

首次運(yùn)行(config.ini不存在):

配置文件config.ini不存在,將創(chuàng)建新文件
配置文件讀取完成,共0個(gè)配置項(xiàng)
=== 讀取配置項(xiàng) ===
姓名:未知
年齡:18
分?jǐn)?shù):60
地址:未設(shè)置
=== 修改配置項(xiàng) ===
配置文件寫入完成!
=== 重新讀取配置項(xiàng) ===
配置文件讀取完成,共4個(gè)配置項(xiàng)
姓名:李四
年齡:22
地址:北京市

生成的config.ini文件內(nèi)容:

# 配置文件:config.ini
# 格式:key=value(#開頭為注釋,空行忽略)
address=北京市
age=22
name=李四
score=95.5

再次運(yùn)行(config.ini已存在):

配置文件讀取完成,共4個(gè)配置項(xiàng)
=== 讀取配置項(xiàng) ===
姓名:李四
年齡:22
分?jǐn)?shù):95.5
地址:北京市
=== 修改配置項(xiàng) ===
配置文件寫入完成!
=== 重新讀取配置項(xiàng) ===
配置文件讀取完成,共4個(gè)配置項(xiàng)
姓名:李四
年齡:22
地址:北京市

? 結(jié)論:該配置文件工具通過文件IO流實(shí)現(xiàn)了INI文件的讀寫,通過字符串IO流實(shí)現(xiàn)了配置項(xiàng)的解析和格式化,支持多種數(shù)據(jù)類型的配置獲取,處理了文件不存在、格式錯(cuò)誤等異常場(chǎng)景,符合IO流的最佳實(shí)踐。

九、總結(jié)

  1. C++ IO流將輸入輸出抽象為“流”,通過統(tǒng)一的接口(>>、<<)實(shí)現(xiàn)控制臺(tái)、文件、內(nèi)存的交互,核心類體系基于ios_baseios派生。
  2. 標(biāo)準(zhǔn)IO流(cin、cout、cerr、clog)用于控制臺(tái)交互,支持豐富的格式控制(如精度、對(duì)齊、進(jìn)制)。
  3. 文件IO流(ifstream、ofstream、fstream)用于文件讀寫,文本文件使用>>/<</getline(),二進(jìn)制文件使用read()/write(),需指定ios::binary模式。
  4. 字符串IO流(istringstream、ostringstream、stringstream)用于內(nèi)存數(shù)據(jù)的格式化與解析,適用于日志拼接、配置解析等場(chǎng)景。
  5. 自定義類型可通過重載>><<運(yùn)算符支持IO流操作,提升代碼靈活性。
  6. 最佳實(shí)踐:檢查文件打開狀態(tài)、處理流狀態(tài)異常、明確文件模式、合理管理資源,避免常見錯(cuò)誤。

通過本文學(xué)習(xí),你應(yīng)能熟練運(yùn)用C++ IO流處理各種輸入輸出場(chǎng)景,解決實(shí)際開發(fā)中的文件讀寫、數(shù)據(jù)格式化、配置解析等問題。下一篇將深入探討C++的多線程編程基礎(chǔ),開啟并發(fā)編程的大門!

到此這篇關(guān)于C++ IO流詳解:標(biāo)準(zhǔn)IO、文件IO與字符串IO實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)C++ IO流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++引用概念及用法全解

    C++引用概念及用法全解

    本文詳細(xì)介紹了C++中的引用概念,總結(jié)了引用和指針的關(guān)鍵差異,并強(qiáng)調(diào)引用更安全但靈活性較低,指針則更靈活但需注意空指針等問題,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • C語言實(shí)現(xiàn)萬年歷程序

    C語言實(shí)現(xiàn)萬年歷程序

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)萬年歷程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++深復(fù)制和淺復(fù)制講解

    C++深復(fù)制和淺復(fù)制講解

    這篇文章主要介紹了C++深復(fù)制和淺復(fù)制講解,C++中深復(fù)制和淺復(fù)制最大的區(qū)別在“類包含指針類型的數(shù)據(jù)成員”時(shí),下面感興趣的小伙伴和小編一起進(jìn)入文章了解更多相關(guān)內(nèi)容吧
    2022-03-03
  • 淺談c++的編譯和運(yùn)行

    淺談c++的編譯和運(yùn)行

    下面小編就為大家?guī)硪黄獪\談c++的編譯和運(yùn)行。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • 基于Qml實(shí)現(xiàn)水印工具

    基于Qml實(shí)現(xiàn)水印工具

    這篇文章主要介紹了如何在?Qml?中實(shí)現(xiàn)一個(gè)簡單但功能強(qiáng)大的水印工具,包括水印文本的透明度、顏色、字體大小、旋轉(zhuǎn)角度等自定義功能,需要的可以參考下
    2024-12-12
  • 淺析C++中static的一些用法

    淺析C++中static的一些用法

    static是靜止的,靜態(tài)的意思,那它有什么用呢,今天通過實(shí)例代碼講解下C++中static的一些用法,感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • 淺析c++ 宏 #val 在unicode下的使用

    淺析c++ 宏 #val 在unicode下的使用

    以下是對(duì)c++中宏#val在unicode下的使用方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    本文主要介紹了vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼,文中通過圖文介紹的的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • 淺談哈希表存儲(chǔ)效率一般不超過50%的原因

    淺談哈希表存儲(chǔ)效率一般不超過50%的原因

    下面小編就為大家?guī)硪黄獪\談哈希表存儲(chǔ)效率一般不超過50%的原因。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-01-01
  • C語言學(xué)生成績管理系統(tǒng)源碼

    C語言學(xué)生成績管理系統(tǒng)源碼

    這篇文章主要為大家詳細(xì)介紹了C語言學(xué)生成績管理系統(tǒng)源碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評(píng)論

思南县| 内黄县| 宽城| 靖江市| 新乡市| 元谋县| 西充县| 临澧县| 河津市| 邵阳县| 闸北区| 禹州市| 吉林省| 庆安县| 辽阳县| 湟源县| 磴口县| 靖州| 广德县| 平江县| 孝感市| 望奎县| 蓬莱市| 晋宁县| 沾化县| 长宁县| 宁安市| 平陆县| 翁源县| 时尚| 元阳县| 大悟县| 普洱| 舟曲县| 吴桥县| 铁岭县| 南涧| 三亚市| 琼海市| 梁山县| 车险|