您好,登錄后才能下訂單哦!
本篇內容主要講解“c++文件如何進行讀取和寫入操作”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“c++文件如何進行讀取和寫入操作”吧!
c++文件進行讀取和寫入操作的方法:1、使用“>>”和“<<”運算符;2、使用“istream::read()”和“ostream::write()”方法;3、使用“istream::get()”和“ostream::put()”成員方法。
本教程操作環境:windows7系統、C++17版本、Dell G3電腦。
方法1:C++ >>和<<讀寫文本文件
fstream 或者 ifstream 類負責實現對文件的讀取,它們內部都對 >>
輸出流運算符做了重載;同樣,fstream 和 ofstream 類負責實現對文件的寫入,它們的內部也都對 <<
輸出流運算符做了重載。
所以,當 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↙
其中,↙
表示輸入換行符;^Z
是 Ctrl+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++文件如何進行讀取和寫入操作”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。