首頁 後端開發 C#.Net教程 c++檔案怎麼會讀取和寫入操作

c++檔案怎麼會讀取和寫入操作

Jun 28, 2021 pm 03:18 PM
c++ 文件

c 檔案進行讀取和寫入操作的方法:1、使用「>>」和「<<」運算子;2、使用「istream::read()」和「 ostream::write()」方法;3、使用「istream::get()」和「ostream::put()」成員方法。

c++檔案怎麼會讀取和寫入操作

本教學操作環境:windows7系統、C 17版本、Dell G3電腦。

方法1:C >>和<<讀寫文字檔案

fstream 或ifstream 類別負責實作對檔案的讀取,它們內部都對>> 輸出流運算子做了重載;同樣,fstream 和ofstream 類別負責實現對檔案的寫入,它們的內部也都對<code>&lt ;< 輸出流運算子做了重載。

所以,當fstream 或ifstream 類別物件開啟檔案(通常以ios::in 作為開啟模式)之後,就可以直接使用>> 輸入流運算符,讀取檔案中儲存的字元(或字串);當fstream 或ofstream 類別物件開啟檔案(通常以ios::out 作為開啟模式)後,可以直接使用<< 輸出流運算子在檔案中寫入字元(或字串)。

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    int x,sum=0;
    ifstream srcFile("in.txt", ios::in); //以文本模式打开in.txt备读
    if (!srcFile) { //打开失败
        cout << "error opening source file." << endl;
        return 0;
    }
    ofstream destFile("out.txt", ios::out); //以文本模式打开out.txt备写
    if (!destFile) {
        srcFile.close(); //程序结束前不能忘记关闭以前打开过的文件
        cout << "error opening destination file." << endl;
        return 0;
    }
    //可以像用cin那样用ifstream对象
    while (srcFile >> x) {
        sum += x;
        //可以像 cout 那样使用 ofstream 对象
        destFile << x << " ";
    }
    cout << "sum:" << sum << endl;
    destFile.close();
    srcFile.close();
    return 0;
}
登入後複製

執行此程式之前,必須在和該程式原始檔同目錄中手動建立一個in.txt 文件,假設其內部儲存的字串為:

10 20 30 40 50
登入後複製

建立之後,執行程序,其執行結果為:

sum:150
登入後複製

同時在in.txt 文件同目錄下,會產生一個out.txt 文件,其內部儲存的字元和in.txt 文件完全一樣,讀者可自行開啟文件查看。

透過分析程式的執行結果不難理解,對於in.txt 檔案中的"10 20 30 40 50" 字串,srcFile 物件會依序將"10"、"20"、"30"、 "40"、"50" 讀取出來,將它們解析成int 類型的整數10、20、30、40、50 並賦值給x,同時完成和sum 的加和操作。

同樣,對於每次從in.txt 檔案讀取並解析出的整形x,destFile 物件都會原封不動地將其再解析成對應的字串(如整數10 解析成字串" 10"),然後和" " 空格符號一起寫入out.txt 檔案。

方法2:C read()和write()讀寫二進位檔案

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

ofstream 和fstream 的write() 成員方法實際上繼承自ostream 類,其功能是將記憶體中buffer 指向的count 個位元組的內容寫入文件,基本格式如下:

ostream & write(char* buffer, int count);
登入後複製

其中,buffer 用於指定要寫入檔案的二進位資料的起始位置;count 用於指定寫入位元組的個數。

也就是說,該方法可以被 ostream 類別的 cout 物件調用,常用於向螢幕上輸出字串。同時,它還可以被 ofstream 或 fstream 物件調用,用於將指定個數的二進位資料寫入檔案。

同時,方法會傳回一個作用於函數的參考形式的物件。舉個例子,obj.write() 方法的回傳值就是 obj 物件的參考。

要注意的一點是,write() 成員方法向檔案中寫入若干字節,可是呼叫 write() 函數時並沒有指定這些位元組寫入檔案中的具體位置。事實上,write() 方法會從檔案寫入指標指向的位置將二進位資料寫入。所謂文件寫指針,是是ofstream 或fstream 物件內部維護的變量,文件剛打開時,文件寫指針指向的是文件的開頭(如果以ios::app 方式打開,則指向文件末尾),用write( ) 方法寫入n 個位元組,寫入指標指向的位置就向後移動n 個位元組。

下面的程式示範如何將學生資訊以二進位形式寫入檔案:

#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組合鍵結束輸入。

執行程式後,會自動產生一個students.dat 文件,其內部存有72 個位元組的數據,如果用「記事本」開啟此文件,可能看到如下亂碼:

Tom 烫烫烫烫烫烫烫烫<   Jack 烫烫烫烫烫烫烫蘌   Jane 烫烫烫烫烫烫烫?
登入後複製

值得一提的是,程式中第13 行指定檔案的開啟模式為ios::out | ios::binary,即以二進位寫入模式開啟。在 Windows平台中,以二進位模式開啟檔案是非常必要的,否則可能出錯。

另外,第 15 行將 s 物件寫入檔案。 s 的位址就是要寫入檔案的記憶體緩衝區的位址,但是&s 不是char * 類型,因此要進行強制類型轉換;第16 行,檔案使用完畢一定要關閉,否則程式結束後檔案的內容可能不完整。

C istream::read()方法讀取檔案

ifstream 和fstream 的read() 方法實際上是繼承自istream 類,其功能正好和write()方法相反,即從檔案中讀取count 個位元組的資料。此方法的語法格式如下:

istream & read(char* buffer, int count);
登入後複製

其中,buffer 用于指定读取字节的起始位置,count 指定读取字节的个数。同样,该方法也会返回一个调用该方法的对象的引用。

和 write() 方法类似,read() 方法从文件读指针指向的位置开始读取若干字节。所谓文件读指针,可以理解为是 ifstream 或 fstream 对象内部维护的一个变量。文件刚打开时,文件读指针指向文件的开头(如果以 ios::app 方式打开,则指向文件末尾),用 read() 方法读取 n 个字节,读指针指向的位置就向后移动 n 个字节。因此,打开一个文件后连续调用 read() 方法,就能将整个文件的内容读取出来。

通过执行 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))) { //一直读到文件结束
        cout << s.szName << " " << s.age << endl;   
    }
    inFile.close();
    return 0;
}
登入後複製

程序的输出结果是:

Tom 60
Jack 80
Jane 40
登入後複製

注意,程序中第 18 行直接将 read() 方法作为 while 循环的判断条件,这意味着,read() 方法会一直读取到文件的末尾,将所有字节全部读取完毕,while 循环才会终止。

方法3:C++ get()和put()读写文件

在某些特殊的场景中,我们可能需要逐个读取文件中存储的字符,或者逐个将字符存储到文件中。这种情况下,就可以调用 get() 和 put() 成员方法实现。

C++ ostream::put()成员方法

我们知道,fstream 和 ofstream 类继承自 ostream 类,因此 fstream 和 ofstream 类对象都可以调用 put() 方法。

当 fstream 和 ofstream 文件流对象调用 put() 方法时,该方法的功能就变成了向指定文件中写入单个字符。put() 方法的语法格式如下:

ostream& put (char c);
登入後複製

其中,c 用于指定要写入文件的字符。该方法会返回一个调用该方法的对象的引用形式。例如,obj.put() 方法会返回 obj 这个对象的引用。

举个例子:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    char c;
    //以二进制形式打开文件
    ofstream outFile("out.txt", ios::out | ios::binary);
    if (!outFile) {
        cout << "error" << endl;
        return 0;
    }
    while (cin >> c) {
        //将字符 c 写入 out.txt 文件
        outFile.put(c);
    }
    outFile.close();
    return 0;
}
登入後複製

执行程序,输入:

https://www.php.cn/↙
^Z↙
登入後複製

其中,表示输入换行符;^ZCtrl+Z 的组合键,表示输入结束。

由此,程序中通过执行 while 循环,会将 "https://www.php.cn/" 字符串的字符逐个复制给变量 c,并逐个写入到 out.txt 文件。

注意,由于文件存放在硬盘中,硬盘的访问速度远远低于内存。如果每次写一个字节都要访问硬盘,那么文件的读写速度就会慢得不可忍受。因此,操作系统在接收到 put() 方法写文件的请求时,会先将指定字符存储在一块指定的内存空间中(称为文件流输出缓冲区),等刷新该缓冲区(缓冲区满、关闭文件、手动调用 flush() 方法等,都会导致缓冲区刷新)时,才会将缓冲区中存储的所有字符“一股脑儿”全写入文件。

C++ istream::get()成员方法

和 put() 成员方法的功能相对的是 get() 方法,其定义在 istream 类中,借助 cin.get() 可以读取用户输入的字符。在此基础上,fstream 和 ifstream 类继承自 istream 类,因此 fstream 和 ifstream 类的对象也能调用 get() 方法。

当 fstream 和 ifstream 文件流对象调用 get() 方法时,其功能就变成了从指定文件中读取单个字符(还可以读取指定长度的字符串)。值得一提的是,get() 方法的语法格式有很多(请猛击这里了解详情),这里仅介绍最常用的 2 种:

int get();
istream& get (char& c);
登入後複製

其中,第一种语法格式的返回值就是读取到的字符,只不过返回的是它的 ASCII 码,如果碰到输入的末尾,则返回值为 EOF。第二种语法格式需要传递一个字符变量,get() 方法会自行将读取到的字符赋值给这个变量。

本节前面在讲解 put() 方法时,生成了一个 out.txt 文件,下面的样例演示了如何通过 get() 方法逐个读取 out.txt 文件中的字符:

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
    char c;
    //以二进制形式打开文件
    ifstream inFile("out.txt", ios::out | ios::binary);
    if (!inFile) {
        cout << "error" << endl;
        return 0;
    }
    while ( (c=inFile.get())&&c!=EOF )   //或者 while(inFile.get(c)),对应第二种语法格式
    {
        cout << c ;
    }
    inFile.close();
    return 0;
}
登入後複製

程序执行结果为:

https://www.php.cn/
登入後複製

注意,和 put() 方法一样,操作系统在接收到 get() 方法的请求后,哪怕只读取一个字符,也会一次性从文件中将很多数据(通常至少是 512 个字节,因为硬盘的一个扇区是 512 B)读到一块内存空间中(可称为文件流输入缓冲区),这样当读取下一个字符时,就不需要再访问硬盘中的文件,直接从该缓冲区中读取即可。

更多编程相关知识,请访问:编程视频!!

以上是c++檔案怎麼會讀取和寫入操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

C#與C:歷史,進化和未來前景 C#與C:歷史,進化和未來前景 Apr 19, 2025 am 12:07 AM

C#和C 的歷史與演變各有特色,未來前景也不同。 1.C 由BjarneStroustrup在1983年發明,旨在將面向對象編程引入C語言,其演變歷程包括多次標準化,如C 11引入auto關鍵字和lambda表達式,C 20引入概念和協程,未來將專注於性能和系統級編程。 2.C#由微軟在2000年發布,結合C 和Java的優點,其演變注重簡潔性和生產力,如C#2.0引入泛型,C#5.0引入異步編程,未來將專注於開發者的生產力和雲計算。

Golang和C:並發與原始速度 Golang和C:並發與原始速度 Apr 21, 2025 am 12:16 AM

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

表演競賽:Golang vs.C 表演競賽:Golang vs.C Apr 16, 2025 am 12:07 AM

Golang和C 在性能競賽中的表現各有優勢:1)Golang適合高並發和快速開發,2)C 提供更高性能和細粒度控制。選擇應基於項目需求和團隊技術棧。

Golang和C:性能的權衡 Golang和C:性能的權衡 Apr 17, 2025 am 12:18 AM

Golang和C 在性能上的差異主要體現在內存管理、編譯優化和運行時效率等方面。 1)Golang的垃圾回收機制方便但可能影響性能,2)C 的手動內存管理和編譯器優化在遞歸計算中表現更為高效。

Python與C:學習曲線和易用性 Python與C:學習曲線和易用性 Apr 19, 2025 am 12:20 AM

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。

在 visual studio code 中使用 c 嗎 在 visual studio code 中使用 c 嗎 Apr 15, 2025 pm 08:03 PM

在 VS Code 中編寫 C 語言不僅可行,而且高效優雅。關鍵在於安裝優秀的 C/C 擴展,它提供代碼補全、語法高亮和調試等功能。 VS Code 的調試功能可幫助你快速定位 bug,而 printf 輸出是老式但有效的調試方法。此外,動態內存分配時應檢查返回值並釋放內存以防止內存洩漏,調試這些問題在 VS Code 中很方便。雖然 VS Code 無法直接幫助進行性能優化,但它提供了一個良好的開發環境,便於分析代碼性能。良好的編程習慣、可讀性和可維護性也至關重要。總之,VS Code 是一

VSCode怎麼用 VSCode怎麼用 Apr 15, 2025 pm 11:21 PM

Visual Studio Code (VSCode) 是一款跨平台、開源且免費的代碼編輯器,由微軟開發。它以輕量、可擴展性和對眾多編程語言的支持而著稱。要安裝 VSCode,請訪問官方網站下載並運行安裝程序。使用 VSCode 時,可以創建新項目、編輯代碼、調試代碼、導航項目、擴展 VSCode 和管理設置。 VSCode 適用於 Windows、macOS 和 Linux,支持多種編程語言,並通過 Marketplace 提供各種擴展。它的優勢包括輕量、可擴展性、廣泛的語言支持、豐富的功能和版

See all articles