欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++使用read()和write()讀寫二進制文件

 更新時間:2023年10月09日 09:36:39   作者:向陽逐夢  
以文本形式讀寫文件和以二進制形式讀寫文件的區(qū)別,并掌握了用重載的?>>?和?<<?運算符實現(xiàn)以文本形式讀寫文件,在此基礎上,本節(jié)將講解如何以二進制形式讀寫文件

學籍管理程序

舉個例子,現(xiàn)在要做一個學籍管理程序,其中一個重要的工作就是記錄學生的學號、姓名、年齡等信息。這意味著,我們需要用一個類來表示學生,如下所示:

    class CStudent
    {
        char szName[20];  //假設學生姓名不超過19個字符,以 '\0' 結(jié)尾
        char szId[l0];  //假設學號為9位,以 '\0' 結(jié)尾
        int age;  //年齡
    };

以文本形式讀寫文件

前面章節(jié)中,我們學會了如何以文本形式讀寫文件,如果使用此方式存儲學生的信息,則最終的文件中存儲的學生信息可能是這個樣子:

Micheal Jackson 110923412 17Tom Hanks 110923413 18......

要知道,這種存儲學生信息的方式不但浪費空間,而且后期不利于查找指定學生的信息(查找效率低下),因為每個學生的信息所占用的字節(jié)數(shù)不同。

這種情況下,以二進制形式將學生信息存儲到文件中,是非常不錯的選擇,因為以此形式存儲學生信息,可以直接把 CStudent 對象寫入文件中,這意味著每個學生的信息都只占用 sizeof(CStudent) 個字節(jié)。

值得一提的是,要實現(xiàn)以二進制形式讀寫文件,<< 和 >> 將不再適用,需要使用 C++ 標準庫專門提供的 read() 和 write() 成員方法。

其中,read() 方法用于以二進制形式從文件中讀取數(shù)據(jù);write() 方法用于以二進制形式將數(shù)據(jù)寫入文件。

C++ ostream::write()方法寫文件

ofstream 和 fstream 的 write() 成員方法實際上繼承自 ostream 類,其功能是將內(nèi)存中 buffer 指向的 count 個字節(jié)的內(nèi)容寫入文件,基本格式如下:

ostream & write(char* buffer, int count);

其中,buffer 用于指定要寫入文件的二進制數(shù)據(jù)的起始位置;count 用于指定寫入字節(jié)的個數(shù)。

也就是說,該方法可以被 ostream 類的 cout 對象調(diào)用,常用于向屏幕上輸出字符串。同時,它還可以被 ofstream 或者 fstream 對象調(diào)用,用于將指定個數(shù)的二進制數(shù)據(jù)寫入文件。

同時,該方法會返回一個作用于該函數(shù)的引用形式的對象。舉個例子,obj.write() 方法的返回值就是對 obj 對象的引用。需要注意的一點是,write() 成員方法向文件中寫入若干字節(jié),可是調(diào)用 write() 函數(shù)時并沒有指定這些字節(jié)寫入文件中的具體位置。

事實上,write() 方法會從文件寫指針指向的位置將二進制數(shù)據(jù)寫入。所謂文件寫指針,是是 ofstream 或 fstream 對象內(nèi)部維護的一個變量,文件剛打開時,文件寫指針指向的是文件的開頭(如果以 ios::app 方式打開,則指向文件末尾),用 write() 方法寫入 n 個字節(jié),寫指針指向的位置就向后移動 n 個字節(jié)。

下面的程序演示了如何將學生信息以二進制形式寫入文件:

    #include <iostream>
    #include <fstream>
    using namespace std;
    class CStudent
    {
    public:
        char szName[20];
        int age;
    };
    int main()
    {
        CStudent s;
        ofstream outFile("students.dat", ios::out | ios::binary);
        while (cin >> s.szName >> s.age)
            outFile.write((char*)&s, sizeof(s));
        outFile.close();
        return 0;
    }

輸入:

Tom 60↙
Jack 80↙
Jane 40↙
^Z↙

其中,表示輸出換行符,^Z 表示輸入Ctrl+Z組合鍵結(jié)束輸入。執(zhí)行程序后,會自動生成一個 students.dat 文件,其內(nèi)部存有 72 字節(jié)的數(shù)據(jù),如果用“記事本”打開此文件,可能看到如下亂碼:

Tom 燙燙燙燙燙燙燙燙<   Jack 燙燙燙燙燙燙燙蘌   Jane 燙燙燙燙燙燙燙?

值得一提的是,程序中第 13 行指定文件的打開模式為 ios::out | ios::binary,即以二進制寫模式打開。在 Windows平臺中,以二進制模式打開文件是非常有必要的,否則可能出錯,原因會在《文件的文本打開方式和二進制打開方式的區(qū)別》一節(jié)中介紹。另外,第 15 行將 s 對象寫入文件。s 的地址就是要寫入文件的內(nèi)存緩沖區(qū)的地址,但是 &s 不是 char * 類型,因此要進行強制類型轉(zhuǎn)換;第 16 行,文件使用完畢一定要關(guān)閉,否則程序結(jié)束后文件的內(nèi)容可能不完整。

C++ istream::read()方法讀文件

ifstream 和 fstream 的 read() 方法實際上繼承自 istream 類,其功能正好和 write() 方法相反,即從文件中讀取 count 個字節(jié)的數(shù)據(jù)。該方法的語法格式如下:

istream & read(char* buffer, int count);

其中,buffer 用于指定讀取字節(jié)的起始位置,count 指定讀取字節(jié)的個數(shù)。同樣,該方法也會返回一個調(diào)用該方法的對象的引用。

和 write() 方法類似,read() 方法從文件讀指針指向的位置開始讀取若干字節(jié)。所謂文件讀指針,可以理解為是 ifstream 或 fstream 對象內(nèi)部維護的一個變量。文件剛打開時,文件讀指針指向文件的開頭(如果以 ios::app 方式打開,則指向文件末尾),用 read() 方法讀取 n 個字節(jié),讀指針指向的位置就向后移動 n 個字節(jié)。因此,打開一個文件后連續(xù)調(diào)用 read() 方法,就能將整個文件的內(nèi)容讀取出來。通過執(zhí)行 write() 方法的示例程序,我們將 3 個學生的信息存儲到了 students.dat 文件中,下面程序演示了如何使用 read() 方法將它們讀取出來:

    #include <iostream>
    #include <fstream>
    using namespace std;
    class CStudent
    {
    public:
        char szName[20];
        int age;
    };
    int main()
    {
        CStudent s;       
        ifstream inFile("students.dat",ios::in|ios::binary); //二進制讀方式打開
        if(!inFile) {
            cout << "error" <<endl;
            return 0;
        }
        while(inFile.read((char *)&s, sizeof(s))) { //一直讀到文件結(jié)束
            cout << s.szName << " " << s.age << endl;   
        }
        inFile.close();
        return 0;
    }

程序的輸出結(jié)果是:

Tom 60
Jack 80
Jane 40

注意

程序中第 18 行直接將 read() 方法作為 while 循環(huán)的判斷條件,這意味著,read() 方法會一直讀取到文件的末尾,將所有字節(jié)全部讀取完畢,while 循環(huán)才會終止。

另外,在使用 read() 方法的同時,如果想知道一共成功讀取了多少個字節(jié)(讀到文件尾時,未必能讀取 count 個字節(jié)),可以在 read() 方法執(zhí)行后立即調(diào)用文件流對象的 gcount() 成員方法,其返回值就是最近一次 read() 方法成功讀取的字節(jié)數(shù)。感興趣的讀者可自行嘗試,這里不再做具體演示,更多關(guān)于C++ 讀寫二進制文件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解C++中虛析構(gòu)函數(shù)的作用及其原理分析

    詳解C++中虛析構(gòu)函數(shù)的作用及其原理分析

    這篇文章主要介紹了C++中虛析構(gòu)函數(shù)的作用及其原理分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • C語言中數(shù)據(jù)的存儲詳解

    C語言中數(shù)據(jù)的存儲詳解

    這篇文章主要介紹了C語言中數(shù)據(jù)的存儲詳解的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • C++實現(xiàn)哈夫曼樹的方法

    C++實現(xiàn)哈夫曼樹的方法

    這篇文章主要為大家詳細介紹了C++實現(xiàn)哈夫曼樹的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 關(guān)于Qt添加opencv和libtorch庫的問題

    關(guān)于Qt添加opencv和libtorch庫的問題

    這篇文章主要介紹了Qt添加opencv和libtorch庫的相關(guān)知識,兩種方法一種是通過手動添加,一種是通過qt creator添加,需要的朋友可以參考下
    2022-01-01
  • C++排序算法之冒泡排序解析

    C++排序算法之冒泡排序解析

    這篇文章主要介紹了C++排序算法之冒泡排序解析,從左到右,相鄰兩數(shù)兩兩比較,若下標小的數(shù)大于下標大的數(shù)則交換,將最大的數(shù)放在數(shù)組的最后一位,,再次遍歷數(shù)組,將第二大的數(shù),放在數(shù)組倒數(shù)第二的位置,以此類推,直到數(shù)組有序需要的朋友可以參考下
    2023-10-10
  • vscode編譯運行c語言報錯亂碼的解決

    vscode編譯運行c語言報錯亂碼的解決

    本文主要介紹了vscode編譯運行c語言報錯亂碼,文中通過圖文介紹的的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • C++中順序表操作的示例代碼

    C++中順序表操作的示例代碼

    這篇文章主要為大家詳細介紹了C++中順序表的基礎操作的相關(guān)代碼,主要有順序表的輸出、插入和刪除數(shù)據(jù)等,感興趣的小伙伴可以了解一下
    2022-10-10
  • C語言中的鏈接編寫教程

    C語言中的鏈接編寫教程

    這篇文章主要介紹了C語言中的鏈接編寫教程,是C語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-08-08
  • ipv6實現(xiàn)tcp編程示例

    ipv6實現(xiàn)tcp編程示例

    這篇文章主要介紹了ipv6實現(xiàn)tcp編程示例,需要的朋友可以參考下
    2014-03-03
  • 封裝常用正則表達式的用法

    封裝常用正則表達式的用法

    這篇文章主要介紹了使用C++封裝常用正則表達式的用法,方便以后直接使用,最后還給出了測試代碼,大家可運行測試使用
    2014-03-03

最新評論