c 檔案進行讀取和寫入操作的方法:1、使用「>>」和「46e94026d4a1b9ba6b3cb6b0cc675e58>和9cda385aaedac9421af96ea03018ba27> 輸出流運算子做了重載;同樣,fstream 和ofstream 類別負責實現對檔案的寫入,它們的內部也都對
< ;276dc579a566bfbd8fccb836009d79bd> 輸入流運算符,讀取檔案中儲存的字元(或字串);當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++檔案怎麼會讀取和寫入操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!