windows c++ 流讀取文件長度 ios::in ios::binary


問題描述:

  當用ios::in模式打開文件時,使用seekg和tellg讀取文件的長度,將讀取文件內容輸出到控制台,發現亂碼。

 1 int _tmain(int argc, _TCHAR* argv[])
 2 {
 3     using namespace std;
 4     ifstream stream("F:\\WorkSpace\\StreamDemo\\Debug\\abc.txt", ios::in);
 5     if(!stream)
 6         cerr << "Open failed" << endl;
 7     stream.seekg(0, ios::end);
 8     int len = stream.tellg();
 9     stream.seekg(0, ios::beg);
10     char* buffer = new char[len];
11     memset(buffer, '\0', len);
12     if(!stream.read(buffer, len))
13     {
14         cout << "Read error:" << stream.rdstate() << endl;
15     }
16     cout.write(buffer, len);
17     stream.close();
18     system("pause");
19     return 0;
20 }

abc.txt文件內容:

  

運行結果如下:

讀出結果錯誤,輸出到控制台文件,最后有兩個亂碼。

而將ios::in改為ios::binary之后,運行結果如下

單步調試發現,得到的len為8,而文件中的內容本以為是a\naaa\n,應該是6個。

經調查,發現在windows的文本文件中換行是兩個字符\r\n,所以文件中的內容為a\r\naaa\r\n這8個字符。

而用ios::in方式讀入的文件為a\naaa\n,所以len超過文件末尾。

而用ios::binary方式讀入的文件為a\r\naaa\r\n,得到正確的結果。

又改使用了get()來獲得結果,依然發現得到的結果是a\naaa\n。

 

得出以下結論:

1. 以ios::in方式讀入的文件,/r/n讀取內存之后會被認為是同一個字符/n,/n寫入文件變成/r/n

2. 以ios::binary方式讀取的文件,/r/n讀取內存之后會被認為是兩個字符,寫入文件時,必須把換行符寫入為/r/n,否則起不到換行效果。

3. 上述seekg和tellg的方式,用作計算ios::in方式打開的文件長度,實際值大於文件讀入之后的長度。不能用read讀取文件,可用get或getline代替。

 

尚沒有找到簡單完美的方式解決流讀取文件大小的問題,如果你有好的方法,請回復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM