用fstream讀寫文件容易犯的錯
- 2019 年 11 月 15 日
- 筆記
系統學習Windows客戶端開發
fstream屬於C++標準,使用fstream進行文件讀寫,具有跨平台性。使用過程中要注意幾點:
第一,構造函數中指定文件路徑時內部會調用open(),如果再次調用open(),調用將會返回失敗。
第二,判斷文件打開是否成功,使用is_open()介面,不能使用bad()介面,bad()介面是用來判斷讀寫是否有錯。
第三,如果文件內容有包含 ,open()時指定fstream::binary標誌位進行二進位流的讀寫。如果寫文件希望追加不清除原有內容,open()時指定fstream::app標誌位(append的縮寫)。
第四,為了計算文件大小,需要先將位置指向結尾,這時要調seekg(0, ios_base::end),而不是seekg(ios_base::end),seekg有兩個重載函數,只帶一個參數的介面表示相對開始的位置,ios_base::end的值為2,seekg(ios_base::end)表示移到2的位置,而不是文件末尾。
第五,慎用操作符>>和<<讀寫文件,操作符>>和<<類似於scanf()介面,它是基於字元串格式化輸入輸出,比如unsigned short x=200, y=300; ofs <<x<<y;文件內容是字元串200300,而不是數值c8002c01,因為操作符<<會先將數值轉化為字元串再寫入文件。ifs>>x>>y;操作符>>讀取x和y時,首先獲得字元串200300,再賦值給x,因為x是unsigned short類型最大值為65535,200300超過65535,讀取失敗。所以某些場景下用操作符<<和>>進行文件讀寫是不可逆,應該用read(), write()介面讀寫。
下面程式碼詳細演示fstream的使用及要注意的地方。
#include <string> #include <fstream> using namespace std; #pragma pack(1) struct CPoint { public: char m_cType = 0; // 0 down, 1 up, 2 move unsigned short m_nX = 0; unsigned short m_nY = 0; }; #pragma pack() int main() { const std::wstring strFilePath = L"C:\test.dat"; CPoint pt; pt.m_cType = 0; pt.m_nX = 200; pt.m_nY = 300; ofstream ofs(strFilePath.c_str(), fstream::out | fstream::binary); if (ofs.is_open()) { // 判斷文件打開是否成功,使用is_open() // 不能使用bad(),bad()用來判斷讀寫有沒錯誤 // 操作符<<輸出整型時,並不是存儲數值,而是將數值格式化成字元串後存儲, // 此時文件內容第一位元組是數值0,然後是字元串200300 ofs << pt.m_cType << pt.m_nX << pt.m_nY; ofs.close(); } ifstream ifs(strFilePath.c_str(), fstream::in | fstream::binary); if (ifs.is_open()) { // 操作符>>輸入整型時,會掃描數字串直到非數字為止, // 此時掃描到字元串是200300,然後轉化為unsigned short賦值給m_nX, // 因為200300超過unsigned short最大值65535,讀取失敗 CPoint pt2; ifs >> pt2.m_cType >> pt2.m_nX >> pt2.m_nY; printf("x= %d, y = %dn", pt2.m_nX, pt2.m_nY); // 輸出的值是 0, 0 ifs.close(); } // 下面是正確程式碼,使用read(),write()來實現 ofstream ofs2(strFilePath.c_str(), fstream::out | fstream::binary); if (ofs2.is_open()) { ofs2.write((const char*)&pt, sizeof(pt)); ofs2.close(); } ifstream ifs2(strFilePath.c_str(), fstream::in | fstream::binary); if (ifs2.is_open()) { CPoint pt2; ifs2.read((char*)&pt2, sizeof(pt2)); printf("x= %d, y = %dn", pt2.m_nX, pt2.m_nY); // 輸出的值是 200, 300 ifs2.close(); } return 0; }