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

C++文件流操作方式

 更新時(shí)間:2026年05月11日 10:09:16   作者:代碼中介商  
文章介紹了C++中的IO流體系,與C語言文件操作的對(duì)比,文中詳細(xì)描述了流體系的層次、常用流類對(duì)象、輸入輸出控制、文件流操作等并,并并詳細(xì)對(duì)比了C++IO流與C語言文件操作的區(qū)別,最終總結(jié)了C++IO流體系的設(shè)計(jì)優(yōu)勢(shì)與使用要點(diǎn)

引言

在 C 語言中,文件操作依賴于 FILE* 和一系列函數(shù)(fopen、fread、fwrite、fprintf 等)。這種方式雖然功能齊全,但存在類型不安全、容易忘記關(guān)閉文件、錯(cuò)誤處理繁瑣等問題。

C++ 引入了流(Stream)的概念,將輸入輸出抽象為"數(shù)據(jù)流",通過統(tǒng)一的接口操作不同的設(shè)備(鍵盤、屏幕、文件、字符串等)。流體系基于面向?qū)ο笤O(shè)計(jì),提供了類型安全、可擴(kuò)展的 IO 操作方式。

第一部分:IO 流類層次體系

一、完整繼承關(guān)系

二、常用頭文件與類

頭文件包含的類用途
<iostream>cincoutcerrclog標(biāo)準(zhǔn)控制臺(tái) IO
<fstream>ifstreamofstreamfstream文件 IO
<sstream>istringstreamostringstreamstringstream字符串 IO
<iomanip>操縱符函數(shù)(setwsetprecision 等)格式控制

三、四個(gè)標(biāo)準(zhǔn)流對(duì)象

#include <iostream>
using namespace std;
// cin   — istream 對(duì)象,關(guān)聯(lián)標(biāo)準(zhǔn)輸入(鍵盤)
// cout  — ostream 對(duì)象,關(guān)聯(lián)標(biāo)準(zhǔn)輸出(屏幕)
// cerr  — ostream 對(duì)象,關(guān)聯(lián)標(biāo)準(zhǔn)錯(cuò)誤(無緩沖)
// clog  — ostream 對(duì)象,關(guān)聯(lián)標(biāo)準(zhǔn)日志(有緩沖)

cerr 和 clog 的區(qū)別

cerr << "錯(cuò)誤信息" << endl;   // 立即輸出(無緩沖)
clog << "日志信息" << endl;   // 緩沖后輸出

第二部分:標(biāo)準(zhǔn)輸入流詳解

一、逐字符讀取

#include <iostream>
using namespace std;
int main() {
    char ch;
    // 方式1:get() 獲取一個(gè)字符(返回 istream 引用)
    cin.get(ch);
    // 方式2:get() 返回字符的 ASCII 值(int 類型)
    int ch2 = cin.get();
    cout << ch << ", " << ch2 << endl;
    return 0;
}

get() 的兩種重載對(duì)比

重載形式返回值用途
cin.get(ch)istream&讀取字符存入 ch
cin.get()int返回讀取字符的 ASCII 值(-1 表示 EOF)

二、逐行讀取

char buf[128] = {0};
// 方式1:getline(),遇到換行符結(jié)束
cin.getline(buf, 128);
// 方式2:getline() 指定分隔符
cin.getline(buf, 128, '\n');  // 第三個(gè)參數(shù)是分隔符
// 方式3:read() 讀取指定字節(jié)數(shù)
cin.read(buf, 10);

getline() 與 >> 的區(qū)別

方法遇到空格遇到換行讀取換行符安全性
cin >> buf停止停止不讀?。粼诰彌_區(qū))? 無長(zhǎng)度限制
cin.getline(buf, n)繼續(xù)停止讀取并丟棄? 有長(zhǎng)度限制

三、自定義讀行函數(shù)

#include <string>
// C 風(fēng)格字符串讀取
long readline(char* buf, int maxSize) {
    char ch;
    int len = 0;
    while (true) {
        cin.get(ch);
        if (ch == '\n' || len >= maxSize) break;
        buf[len++] = ch;
    }
    return len;
}
// C++ string 讀取
long readString(string& s) {
    char ch;
    while (true) {
        cin.get(ch);
        if (ch == '\n') break;
        s += ch;
    }
    return s.size();
}

四、緩沖區(qū)管理

cin.ignore();       // 忽略一個(gè)字符(清空緩沖區(qū))
cin.ignore(100);    // 忽略最多 100 個(gè)字符
cin.ignore(100, '\n'); // 忽略直到換行符(最多 100 個(gè))
cin.clear();        // 清除錯(cuò)誤狀態(tài)標(biāo)志

常見場(chǎng)景cin >> n 后殘留的換行符需要清理

int n;
cin >> n;
cin.ignore();  // 清除殘留的 '\n'
// 然后安全讀取下一行
string line;
getline(cin, line);

第三部分:標(biāo)準(zhǔn)輸出流詳解

一、基本輸出方法

// put() — 輸出單個(gè)字符
cout.put('A');
cout.put('\n');
// write() — 輸出指定長(zhǎng)度的字符串
cout.write("hello", 5);  // 輸出5個(gè)字符
// flush() — 強(qiáng)制刷新緩沖區(qū)
cout.flush();
// endl — 輸出換行并刷新
cout << endl;  // 等價(jià)于 cout << '\n' << flush;

輸出緩沖區(qū)的四種刷新時(shí)機(jī)

刷新模式觸發(fā)條件
滿刷新緩沖區(qū)滿時(shí)自動(dòng)刷新
行刷新遇到換行符 \n 時(shí)刷新
程序退出exit() 或 return 時(shí)刷新
強(qiáng)制刷新調(diào)用 flush() 或 endl

二、格式控制 — 進(jìn)制輸出

#include <iomanip>
int n = 100;
// 使用操縱符
cout << showbase << hex << n << endl;   // 0x64 (十六進(jìn)制,帶前綴)
cout << oct << n << endl;              // 0144  (八進(jìn)制)
cout << dec << n << endl;              // 100   (十進(jìn)制)
// showbase — 顯示進(jìn)制前綴(0x 或 0)
// noshowbase — 取消進(jìn)制前綴
操縱符效果
hex十六進(jìn)制輸出
oct八進(jìn)制輸出
dec十進(jìn)制輸出(默認(rèn))
showbase顯示進(jìn)制前綴
noshowbase取消進(jìn)制前綴
uppercase十六進(jìn)制字母大寫
nouppercase十六進(jìn)制字母小寫(默認(rèn))

三、格式控制 — 使用 flags

// 獲取當(dāng)前標(biāo)志
ios::fmtflags old_flags = cout.flags();
// 設(shè)置新標(biāo)志(會(huì)覆蓋舊標(biāo)志)
cout.flags(ios::showbase | ios::hex);
cout << 90 << endl;  // 0x5a
// 恢復(fù)舊標(biāo)志
cout.flags(old_flags);

常用格式標(biāo)志

標(biāo)志含義
ios::showbase顯示進(jìn)制前綴
ios::hex十六進(jìn)制
ios::oct八進(jìn)制
ios::dec十進(jìn)制
ios::left左對(duì)齊
ios::right右對(duì)齊
ios::fixed固定小數(shù)位
ios::scientific科學(xué)計(jì)數(shù)法

四、格式控制 — 寬度和填充

cout.width(20);        // 設(shè)置輸出寬度為 20(只影響下一個(gè)輸出)
cout.fill('*');        // 設(shè)置填充字符為 '*'
cout << left;          // 左對(duì)齊
cout << "hi,disen!" << endl;
// 輸出:hi,disen!***********
// 使用操縱符
cout << setw(20) << setfill('*') << left << "hi,disen!" << endl;
方法/操縱符作用生效范圍
width(n) / setw(n)設(shè)置輸出寬度只影響下一個(gè)輸出
fill(c) / setfill(c)設(shè)置填充字符持久生效
left左對(duì)齊持久生效
right右對(duì)齊持久生效

五、格式控制 — 浮點(diǎn)數(shù)精度

#include <iomanip>
double d = 1.2345678;
// 設(shè)置精度
cout << setprecision(3) << d << endl;  // 1.23
cout << setprecision(1) << 2.459 << endl;  // 2
// 固定小數(shù)位模式
cout << fixed << setprecision(2) << 1.345678 << endl;  // 1.35
// 科學(xué)計(jì)數(shù)法模式
cout << scientific << 123.456 << endl;  // 1.234560e+02
// 默認(rèn)模式
cout << defaultfloat << 99.2389 << endl;
操縱符精度含義
defaultfloat有效數(shù)字位數(shù)(默認(rèn))
fixed小數(shù)點(diǎn)后位數(shù)
scientific小數(shù)點(diǎn)后位數(shù)(科學(xué)計(jì)數(shù)法)

第四部分:文件流詳解

一、文件打開模式

#include <fstream>
// 定義在 ios 中
ios::in        // 讀模式(ifstream 默認(rèn))
ios::out       // 寫模式(ofstream 默認(rèn))
ios::app       // 追加模式(寫入到文件末尾)
ios::ate       // 打開時(shí)定位到文件末尾
ios::trunc     // 打開時(shí)清空文件內(nèi)容
ios::binary    // 二進(jìn)制模式

組合使用

// 讀寫模式,二進(jìn)制
fstream fs("data.dat", ios::in | ios::out | ios::binary);
// 寫模式,追加
ofstream fs("log.txt", ios::out | ios::app);

二、文件寫入

#include <fstream>
#include <cstring>
int main() {
    ofstream fs("a.txt", ios::out);
    if (!fs.good()) {
        cout << "打開文件失敗" << endl;
        return -1;
    }
    char line[128] = {0};
    while (true) {
        cin.getline(line, 128);
        if (strlen(line) == 0) break;
        fs.write(line, strlen(line));
        fs.write("\n", 1);
    }
    fs.close();
    return 0;
}

三、文件讀取

#include <fstream>
#include <string>
int main() {
    ifstream fs("a.txt");  // 默認(rèn) ios::in
    if (!fs.good()) return -1;
    // 方式1:逐行讀取
    string line;
    while (getline(fs, line)) {
        cout << line << endl;
    }
    // 方式2:逐詞讀取
    string word;
    while (fs >> word) {
        cout << word << endl;
    }
    fs.close();
    return 0;
}

注意:代碼中 while (!fs.eof()) 存在一個(gè)常見陷阱:

// ? 有問題的寫法
while (!fs.eof()) {
    fs.getline(buf, 128);
    cout << buf << endl;  // 可能輸出兩次最后一行
}
// ? 正確的寫法(將讀取操作放在循環(huán)條件中)
while (fs.getline(buf, 128)) {
    cout << buf << endl;
}

原理eof() 只在嘗試讀取失敗后才變?yōu)?true,不是"預(yù)知"文件結(jié)束。

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

struct Person {
    int pid;
    char name[32];
    void hi() {
        cout << "pid: " << pid << ", name: " << name << endl;
    }
};
int main() {
    Person p1{1001, "Lucy"}, p2{1002, "Disen"};
    // 二進(jìn)制寫入
    fstream fs("b.dat", ios::out | ios::binary);
    if (!fs.good()) return -1;
    fs.write(reinterpret_cast<char*>(&p1), sizeof(Person));
    fs.write(reinterpret_cast<char*>(&p2), sizeof(Person));
    fs.close();
    // 二進(jìn)制讀取 — 先獲取文件大小
    fstream ifs("b.dat", ios::in | ios::binary);
    if (!ifs.good()) return -1;
    ifs.seekg(0, ios::end);  // 移到文件末尾
    auto len = ifs.tellg();  // 獲取當(dāng)前位置(即文件大?。?
    int n = len / sizeof(Person);
    cout << "Person 個(gè)數(shù): " << n << endl;
    ifs.seekg(0, ios::beg);  // 移回文件開始
    for (int i = 0; i < n; i++) {
        Person p;
        ifs.read(reinterpret_cast<char*>(&p), sizeof(Person));
        p.hi();
    }
    ifs.close();
    return 0;
}

五、文件流狀態(tài)檢查

ifstream fs("test.txt");
// 方法1:good()
if (fs.good()) {
    // 文件打開成功,且沒有錯(cuò)誤
}
// 方法2:is_open()
if (fs.is_open()) {
    // 文件已成功打開
}
// 方法3:直接用作布爾值
if (!fs) {
    // 文件打開失敗
}
狀態(tài)函數(shù)含義
good()流狀態(tài)正常,無任何錯(cuò)誤
eof()到達(dá)文件末尾
fail()操作失敗(可恢復(fù))
bad()嚴(yán)重錯(cuò)誤(不可恢復(fù))
is_open()文件是否打開

六、文件指針定位

ifstream fs("data.txt");
// seekg() — 移動(dòng)讀指針
fs.seekg(0, ios::beg);   // 移到開頭
fs.seekg(0, ios::end);   // 移到末尾
fs.seekg(10, ios::cur);  // 從當(dāng)前位置后移10字節(jié)
// tellg() — 獲取讀指針位置
auto pos = fs.tellg();
// seekp() — 移動(dòng)寫指針(ofstream)
// tellp() — 獲取寫指針位置
定位標(biāo)志含義
ios::beg相對(duì)于文件開頭
ios::cur相對(duì)于當(dāng)前位置
ios::end相對(duì)于文件末尾

第五部分:C 與 C++ IO 對(duì)照表

操作C 語言C++ 流
打開文件fopen("a.txt", "r")ifstream fs("a.txt")
關(guān)閉文件fclose(fp)fs.close() 或析構(gòu)自動(dòng)
讀字符fgetc(fp)fs.get(ch)
讀一行fgets(buf, n, fp)fs.getline(buf, n)
寫字符fputc(ch, fp)fs.put(ch)
寫一行fputs(str, fp)fs << str
二進(jìn)制讀fread(buf, sz, n, fp)fs.read(buf, n)
二進(jìn)制寫fwrite(buf, sz, n, fp)fs.write(buf, n)
文件指針fseek(fp, 0, SEEK_END)fs.seekg(0, ios::end)
獲取位置ftell(fp)fs.tellg()
錯(cuò)誤檢查檢查返回值fs.good() / !fs
格式化輸出fprintf(fp, "%x", n)fs << hex << n

總結(jié)

一、IO 流體系核心類

二、文件操作通用流程

1. 創(chuàng)建流對(duì)象
   ifstream fs("filename", ios::in);

2. 檢查是否打開成功
   if (!fs.good()) { /* 錯(cuò)誤處理 */ }

3. 讀取/寫入操作
   fs >> data; 或 fs.read(buf, size);

4. 關(guān)閉文件
   fs.close();
   // 或者依賴析構(gòu)函數(shù)自動(dòng)關(guān)閉

三、關(guān)鍵記憶點(diǎn)

要點(diǎn)說明
cin.ignore()清除緩沖區(qū)殘留
cout.width(n)只影響下一個(gè)輸出
cout.fill(c)持久生效
while (getline(fs, line))正確的逐行讀取方式
reinterpret_cast<char*>(&obj)二進(jìn)制讀寫結(jié)構(gòu)體時(shí)的類型轉(zhuǎn)換
fs.seekg(0, ios::end)計(jì)算文件大小
RAII 特性流對(duì)象析構(gòu)時(shí)自動(dòng)關(guān)閉文件

C++ IO 流體系是一個(gè)設(shè)計(jì)精巧的面向?qū)ο罂蚣?,它將控制臺(tái)、文件、字符串等不同設(shè)備的輸入輸出統(tǒng)一到一個(gè)繼承層次中。理解流體系的關(guān)鍵在于:

  • 繼承層次istream / ostream 是所有輸入輸出流的基類
  • 格式控制:通過操縱符(manipulator)控制輸出格式
  • RAII 機(jī)制:流對(duì)象析構(gòu)時(shí)自動(dòng)關(guān)閉文件,避免資源泄漏
  • 狀態(tài)檢查:始終檢查 good() 或直接使用流對(duì)象的布爾值判斷

到此這篇關(guān)于C++文件流操作方式的文章就介紹到這了,更多相關(guān)C++文件流操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中的HTTP協(xié)議問題

    C++中的HTTP協(xié)議問題

    這篇文章主要介紹了C++中的HTTP協(xié)議問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C語言入門之浮點(diǎn)數(shù)

    C語言入門之浮點(diǎn)數(shù)

    這篇文章主要為大家介紹了C語言的浮點(diǎn)數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • C++超詳細(xì)梳理lambda和function的使用方法

    C++超詳細(xì)梳理lambda和function的使用方法

    C++在C11標(biāo)準(zhǔn)中引入了匿名函數(shù),即沒有名字的臨時(shí)函數(shù),又稱之為lambda表達(dá)式.lambda表達(dá)式 實(shí)質(zhì)上是創(chuàng)建一個(gè)匿名函數(shù)/對(duì)象,這篇文章主要介紹了lambda和function的使用方法
    2022-08-08
  • C\C++實(shí)現(xiàn)讀寫二進(jìn)制文件的方法詳解

    C\C++實(shí)現(xiàn)讀寫二進(jìn)制文件的方法詳解

    這篇文章主要為大家詳細(xì)介紹了C\C++實(shí)現(xiàn)讀寫二進(jìn)制文件的方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2023-03-03
  • C語言細(xì)致講解線程同步的集中方式

    C語言細(xì)致講解線程同步的集中方式

    多線程中的線程同步可以使用,CreateThread,CreateMutex 互斥鎖實(shí)現(xiàn)線程同步,通過臨界區(qū)實(shí)現(xiàn)線程同步,Semaphore 基于信號(hào)實(shí)現(xiàn)線程同步,CreateEvent 事件對(duì)象的同步,以及線程函數(shù)傳遞單一參數(shù)與多個(gè)參數(shù)的實(shí)現(xiàn)方式
    2022-05-05
  • C語言中free函數(shù)的使用詳解

    C語言中free函數(shù)的使用詳解

    free函數(shù)是釋放之前某一次malloc函數(shù)申請(qǐng)的空間,而且只是釋放空間,并不改變指針的值。下面我們就來詳細(xì)探討下
    2017-05-05
  • C++中map_set的封裝實(shí)現(xiàn)整體代碼

    C++中map_set的封裝實(shí)現(xiàn)整體代碼

    這篇文章主要介紹了C++中map_set封裝實(shí)現(xiàn)的相關(guān)資料,包括源碼解析、仿函數(shù)的使用、迭代器的設(shè)計(jì)以及const迭代器的實(shí)現(xiàn),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-12-12
  • 使用WindowsAPI實(shí)現(xiàn)播放PCM音頻的方法

    使用WindowsAPI實(shí)現(xiàn)播放PCM音頻的方法

    這篇文章主要介紹了使用WindowsAPI實(shí)現(xiàn)播放PCM音頻的方法,很實(shí)用的一個(gè)功能,需要的朋友可以參考下
    2014-08-08
  • c++實(shí)現(xiàn)解析zip文件的示例代碼

    c++實(shí)現(xiàn)解析zip文件的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用c++實(shí)現(xiàn)解析zip文件,并對(duì)流式文件pptx內(nèi)容的修改,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下
    2023-12-12
  • C語言中%zu的用法解讀

    C語言中%zu的用法解讀

    size_t是無符號(hào)整數(shù)類型,用于表示對(duì)象大小或內(nèi)存操作結(jié)果,%zu是C99標(biāo)準(zhǔn)中專為size_t設(shè)計(jì)的printf占位符,避免因類型不匹配導(dǎo)致錯(cuò)誤,使用%u或%d可能引發(fā)跨平臺(tái)兼容性問題,尤其在64位系統(tǒng)中
    2025-08-08

最新評(píng)論

三都| 肇源县| 洞口县| 元朗区| 遵化市| 平遥县| 双城市| 石河子市| 鹰潭市| 蛟河市| 白沙| 荔浦县| 卢湾区| 天等县| 虎林市| 东乡族自治县| 洪雅县| 盐山县| 来安县| 宜宾市| 丰宁| 常宁市| 哈巴河县| 比如县| 和平区| 临安市| 东平县| 五河县| 浦县| 金溪县| 扶绥县| 永胜县| 安西县| 六盘水市| 新津县| 大埔县| 义乌市| 柳林县| 峨边| 阿鲁科尔沁旗| 泸州市|