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

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

青灯夜游
青灯夜游原創
2021-06-28 15:18:3524690瀏覽

c 檔案進行讀取和寫入操作的方法:1、使用「>>」和「46e94026d4a1b9ba6b3cb6b0cc675e58>和9cda385aaedac9421af96ea03018ba27> 輸出流運算子做了重載;同樣,fstream 和ofstream 類別負責實現對檔案的寫入,它們的內部也都對&lt ;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↙

其中,表示输入换行符;^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