您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“c++文件如何進(jìn)行讀取和寫入操作”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“c++文件如何進(jìn)行讀取和寫入操作”吧!
c++文件進(jìn)行讀取和寫入操作的方法:1、使用“>>”和“<<”運(yùn)算符;2、使用“istream::read()”和“ostream::write()”方法;3、使用“istream::get()”和“ostream::put()”成員方法。
本教程操作環(huán)境:windows7系統(tǒng)、C++17版本、Dell G3電腦。
方法1:C++ >>和<<讀寫文本文件
fstream 或者 ifstream 類負(fù)責(zé)實(shí)現(xiàn)對(duì)文件的讀取,它們內(nèi)部都對(duì) >>
輸出流運(yùn)算符做了重載;同樣,fstream 和 ofstream 類負(fù)責(zé)實(shí)現(xiàn)對(duì)文件的寫入,它們的內(nèi)部也都對(duì) <<
輸出流運(yùn)算符做了重載。
所以,當(dāng) fstream 或者 ifstream 類對(duì)象打開(kāi)文件(通常以 ios::in 作為打開(kāi)模式)之后,就可以直接借助 >> 輸入流運(yùn)算符,讀取文件中存儲(chǔ)的字符(或字符串);當(dāng) fstream 或者 ofstream 類對(duì)象打開(kāi)文件(通常以 ios::out 作為打開(kāi)模式)后,可以直接借助 << 輸出流運(yùn)算符向文件中寫入字符(或字符串)。
#include <iostream> #include <fstream> using namespace std; int main() { int x,sum=0; ifstream srcFile("in.txt", ios::in); //以文本模式打開(kāi)in.txt備讀 if (!srcFile) { //打開(kāi)失敗 cout << "error opening source file." << endl; return 0; } ofstream destFile("out.txt", ios::out); //以文本模式打開(kāi)out.txt備寫 if (!destFile) { srcFile.close(); //程序結(jié)束前不能忘記關(guān)閉以前打開(kāi)過(guò)的文件 cout << "error opening destination file." << endl; return 0; } //可以像用cin那樣用ifstream對(duì)象 while (srcFile >> x) { sum += x; //可以像 cout 那樣使用 ofstream 對(duì)象 destFile << x << " "; } cout << "sum:" << sum << endl; destFile.close(); srcFile.close(); return 0; }
執(zhí)行此程序之前,必須在和該程序源文件同目錄中手動(dòng)創(chuàng)建一個(gè) in.txt 文件,假設(shè)其內(nèi)部存儲(chǔ)的字符串為:
10 20 30 40 50
建立之后,執(zhí)行程序,其執(zhí)行結(jié)果為:
sum:150
同時(shí)在 in.txt 文件同目錄下,會(huì)生成一個(gè) out.txt 文件,其內(nèi)部存儲(chǔ)的字符和 in.txt 文件完全一樣,讀者可自行打開(kāi)文件查看。
通過(guò)分析程序的執(zhí)行結(jié)果不難理解,對(duì)于 in.txt 文件中的 "10 20 30 40 50" 字符串,srcFile 對(duì)象會(huì)依次將 "10"、"20"、"30"、"40"、"50" 讀取出來(lái),將它們解析成 int 類型的整數(shù) 10、20、30、40、50 并賦值給 x,同時(shí)完成和 sum 的加和操作。
同樣,對(duì)于每次從 in.txt 文件讀取并解析出的整形 x,destFile 對(duì)象都會(huì)原封不動(dòng)地將其再解析成對(duì)應(yīng)的字符串(如整數(shù) 10 解析成字符串 "10"),然后和 " " 空格符一起寫入 out.txt 文件。
方法2:C++ read()和write()讀寫二進(jìn)制文件
C++ ostream::write()方法寫文件
ofstream 和 fstream 的 write() 成員方法實(shí)際上繼承自 ostream 類,其功能是將內(nèi)存中 buffer 指向的 count 個(gè)字節(jié)的內(nèi)容寫入文件,基本格式如下:
ostream & write(char* buffer, int count);
其中,buffer 用于指定要寫入文件的二進(jìn)制數(shù)據(jù)的起始位置;count 用于指定寫入字節(jié)的個(gè)數(shù)。
也就是說(shuō),該方法可以被 ostream 類的 cout 對(duì)象調(diào)用,常用于向屏幕上輸出字符串。同時(shí),它還可以被 ofstream 或者 fstream 對(duì)象調(diào)用,用于將指定個(gè)數(shù)的二進(jìn)制數(shù)據(jù)寫入文件。
同時(shí),該方法會(huì)返回一個(gè)作用于該函數(shù)的引用形式的對(duì)象。舉個(gè)例子,obj.write() 方法的返回值就是對(duì) obj 對(duì)象的引用。
需要注意的一點(diǎn)是,write() 成員方法向文件中寫入若干字節(jié),可是調(diào)用 write() 函數(shù)時(shí)并沒(méi)有指定這些字節(jié)寫入文件中的具體位置。事實(shí)上,write() 方法會(huì)從文件寫指針指向的位置將二進(jìn)制數(shù)據(jù)寫入。所謂文件寫指針,是是 ofstream 或 fstream 對(duì)象內(nèi)部維護(hù)的一個(gè)變量,文件剛打開(kāi)時(shí),文件寫指針指向的是文件的開(kāi)頭(如果以 ios::app 方式打開(kāi),則指向文件末尾),用 write() 方法寫入 n 個(gè)字節(jié),寫指針指向的位置就向后移動(dòng) n 個(gè)字節(jié)。
下面的程序演示了如何將學(xué)生信息以二進(jì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
組合鍵結(jié)束輸入。
執(zhí)行程序后,會(huì)自動(dòng)生成一個(gè) students.dat 文件,其內(nèi)部存有 72 字節(jié)的數(shù)據(jù),如果用“記事本”打開(kāi)此文件,可能看到如下亂碼:
Tom 燙燙燙燙燙燙燙燙< Jack 燙燙燙燙燙燙燙蘌 Jane 燙燙燙燙燙燙燙?
值得一提的是,程序中第 13 行指定文件的打開(kāi)模式為 ios::out | ios::binary,即以二進(jìn)制寫模式打開(kāi)。在 Windows平臺(tái)中,以二進(jìn)制模式打開(kāi)文件是非常有必要的,否則可能出錯(cuò)。
另外,第 15 行將 s 對(duì)象寫入文件。s 的地址就是要寫入文件的內(nèi)存緩沖區(qū)的地址,但是 &s 不是 char * 類型,因此要進(jìn)行強(qiáng)制類型轉(zhuǎn)換;第 16 行,文件使用完畢一定要關(guān)閉,否則程序結(jié)束后文件的內(nèi)容可能不完整。
C++ istream::read()方法讀文件
ifstream 和 fstream 的 read() 方法實(shí)際上繼承自 istream 類,其功能正好和 write() 方法相反,即從文件中讀取 count 個(gè)字節(jié)的數(shù)據(jù)。該方法的語(yǔ)法格式如下:
istream & read(char* buffer, int count);
其中,buffer 用于指定讀取字節(jié)的起始位置,count 指定讀取字節(jié)的個(gè)數(shù)。同樣,該方法也會(huì)返回一個(gè)調(diào)用該方法的對(duì)象的引用。
和 write() 方法類似,read() 方法從文件讀指針指向的位置開(kāi)始讀取若干字節(jié)。所謂文件讀指針,可以理解為是 ifstream 或 fstream 對(duì)象內(nèi)部維護(hù)的一個(gè)變量。文件剛打開(kāi)時(shí),文件讀指針指向文件的開(kāi)頭(如果以 ios::app 方式打開(kāi),則指向文件末尾),用 read() 方法讀取 n 個(gè)字節(jié),讀指針指向的位置就向后移動(dòng) n 個(gè)字節(jié)。因此,打開(kāi)一個(gè)文件后連續(xù)調(diào)用 read() 方法,就能將整個(gè)文件的內(nèi)容讀取出來(lái)。
通過(guò)執(zhí)行 write() 方法的示例程序,我們將 3 個(gè)學(xué)生的信息存儲(chǔ)到了 students.dat 文件中,下面程序演示了如何使用 read() 方法將它們讀取出來(lái):
#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); //二進(jìn)制讀方式打開(kāi) 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() 方法會(huì)一直讀取到文件的末尾,將所有字節(jié)全部讀取完畢,while 循環(huán)才會(huì)終止。
方法3:C++ get()和put()讀寫文件
在某些特殊的場(chǎng)景中,我們可能需要逐個(gè)讀取文件中存儲(chǔ)的字符,或者逐個(gè)將字符存儲(chǔ)到文件中。這種情況下,就可以調(diào)用 get() 和 put() 成員方法實(shí)現(xiàn)。
C++ ostream::put()成員方法
我們知道,fstream 和 ofstream 類繼承自 ostream 類,因此 fstream 和 ofstream 類對(duì)象都可以調(diào)用 put() 方法。
當(dāng) fstream 和 ofstream 文件流對(duì)象調(diào)用 put() 方法時(shí),該方法的功能就變成了向指定文件中寫入單個(gè)字符。put() 方法的語(yǔ)法格式如下:
ostream& put (char c);
其中,c 用于指定要寫入文件的字符。該方法會(huì)返回一個(gè)調(diào)用該方法的對(duì)象的引用形式。例如,obj.put() 方法會(huì)返回 obj 這個(gè)對(duì)象的引用。
舉個(gè)例子:
#include <iostream> #include <fstream> using namespace std; int main() { char c; //以二進(jìn)制形式打開(kāi)文件 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; }
執(zhí)行程序,輸入:
https://www.php.cn/↙ ^Z↙
其中,↙
表示輸入換行符;^Z
是 Ctrl+Z
的組合鍵,表示輸入結(jié)束。
由此,程序中通過(guò)執(zhí)行 while 循環(huán),會(huì)將 "https://www.php.cn/" 字符串的字符逐個(gè)復(fù)制給變量 c,并逐個(gè)寫入到 out.txt 文件。
注意,由于文件存放在硬盤中,硬盤的訪問(wèn)速度遠(yuǎn)遠(yuǎn)低于內(nèi)存。如果每次寫一個(gè)字節(jié)都要訪問(wèn)硬盤,那么文件的讀寫速度就會(huì)慢得不可忍受。因此,操作系統(tǒng)在接收到 put() 方法寫文件的請(qǐng)求時(shí),會(huì)先將指定字符存儲(chǔ)在一塊指定的內(nèi)存空間中(稱為文件流輸出緩沖區(qū)),等刷新該緩沖區(qū)(緩沖區(qū)滿、關(guān)閉文件、手動(dòng)調(diào)用 flush() 方法等,都會(huì)導(dǎo)致緩沖區(qū)刷新)時(shí),才會(huì)將緩沖區(qū)中存儲(chǔ)的所有字符“一股腦兒”全寫入文件。
C++ istream::get()成員方法
和 put() 成員方法的功能相對(duì)的是 get() 方法,其定義在 istream 類中,借助 cin.get() 可以讀取用戶輸入的字符。在此基礎(chǔ)上,fstream 和 ifstream 類繼承自 istream 類,因此 fstream 和 ifstream 類的對(duì)象也能調(diào)用 get() 方法。
當(dāng) fstream 和 ifstream 文件流對(duì)象調(diào)用 get() 方法時(shí),其功能就變成了從指定文件中讀取單個(gè)字符(還可以讀取指定長(zhǎng)度的字符串)。值得一提的是,get() 方法的語(yǔ)法格式有很多(請(qǐng)猛擊這里了解詳情),這里僅介紹最常用的 2 種:
int get(); istream& get (char& c);
其中,第一種語(yǔ)法格式的返回值就是讀取到的字符,只不過(guò)返回的是它的 ASCII 碼,如果碰到輸入的末尾,則返回值為 EOF。第二種語(yǔ)法格式需要傳遞一個(gè)字符變量,get() 方法會(huì)自行將讀取到的字符賦值給這個(gè)變量。
本節(jié)前面在講解 put() 方法時(shí),生成了一個(gè) out.txt 文件,下面的樣例演示了如何通過(guò) get() 方法逐個(gè)讀取 out.txt 文件中的字符:
#include <iostream> #include <fstream> using namespace std; int main() { char c; //以二進(jìn)制形式打開(kāi)文件 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)),對(duì)應(yīng)第二種語(yǔ)法格式 { cout << c ; } inFile.close(); return 0; }
程序執(zhí)行結(jié)果為:
https://www.php.cn/
注意,和 put() 方法一樣,操作系統(tǒng)在接收到 get() 方法的請(qǐng)求后,哪怕只讀取一個(gè)字符,也會(huì)一次性從文件中將很多數(shù)據(jù)(通常至少是 512 個(gè)字節(jié),因?yàn)橛脖P的一個(gè)扇區(qū)是 512 B)讀到一塊內(nèi)存空間中(可稱為文件流輸入緩沖區(qū)),這樣當(dāng)讀取下一個(gè)字符時(shí),就不需要再訪問(wèn)硬盤中的文件,直接從該緩沖區(qū)中讀取即可。
到此,相信大家對(duì)“c++文件如何進(jìn)行讀取和寫入操作”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。