一个有关fstream类的bug
生活随笔
收集整理的這篇文章主要介紹了
一个有关fstream类的bug
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一個有關fstream類的bug
????近日寫程序需要讀出文件,對讀出的內容作些修改,再寫回到文件中。
突然發現一個莫名其妙的問題,寫回去的時候居然在文件末尾增加了幾個字
符。感到很不可思議。具體代碼如下:
fstream infile;
????????infile.open("c://test.txt", ios::in);
????????infile.seekp(0, ios::end);
????????int iFileLen = infile.tellp();
????????cout << "File len:" << iFileLen << endl;
????????char * pBuff = new char[iFileLen + 1];
????????memset(pBuff, 0, iFileLen + 1);
????????infile.seekp(0, ios::beg);
????????infile.read(pBuff, iFileLen);
????????infile.close();
????????fstream outfile;
????????outfile.open("c://test1.txt", ios::out|ios::trunc);
????????outfile.write(pBuff, iFileLen);
????????outfile.close();
????????delete[] pBuff;
????在文件test.txt中輸入一個字符'.'以及一個回車鍵,用UE打開,發現該
文件有三個字符,十六進制表示如下:2E 0D 0A。而在屏幕中打印出來的文件
大小也是3??墒俏募est1.txt文件大小卻變成了4,其十六進制表示變成了:
2E 0D 0A 00。莫名其妙的多了一個字節??墒敲髅鲗懭氲淖止潝祽撌?啊。
怎么寫到文件中去卻變成了4了呢?很奇怪的問題。難道是write的問題?于是
我換了一種寫文件方式,改成下面的方式:
????????for(int i = 0; i < iFileLen; i++)
?????????? outfile << pBuff[i];
但是結果仍然同上,仍然多了一個字節。于是感到可能是fstream這個類的問
題,以前也發覺該類在使用seekp時會出錯。于是改成用c語言的文件流讀寫
操作,具體實現如下:
?????? FILE * f = fopen("c://test.txt", "r");
fseek(f, 0, SEEK_END);
int len = ftell(f);
printf("the file len: %d /n", len);
fseek(f, 0, SEEK_SET);
????????char??* p = new char[len + 1];
memset(p, 0x00, len + 1);
fread(p, sizeof(char), len, f);
????????fclose(f);
????????f = fopen("c://test1.txt", "w");
????????fwrite(p, sizeof(char), len, f);
????????fclose(f);
????????delete[] p;
????可惜結果仍然沒變。這就比較奇怪了。怎么會出現這種情況呢?明明文件
大小為3,為何寫到另外一個文件中去卻變成了4呢?于是在程序讀出test.txt
文件內容的下一行添加了一條語句:
????????for(int i = 0; i < len; i++)
????????????cout << (int)p[i];
????結果在屏幕上顯示的居然是這個結果:46 10 0。居然沒有把0A輸出。而是
輸出了0。我突然想到fread返回的結果是真正讀到數據p中的長度,于是我又改
變了一下上面的程序,將fread的結果打印出來:
????????cout << fread(p, sizeof(char), len, f) << endl;
結果果然是2,而不是想當然的3。原來在window下,回車換行的兩個字符讀到
一個數組中去時,只會在數組中保存一個字符:0D。但是用feek來計算文件長
度時返回的卻是文件的實際大小,而不是真正讀入到數組中的值。
????于是,采用fstream類來寫入的時候,文件中每多一個回車換行,實際用
read函數讀到字符數組中的個數就減少一個。而前面我仍然用文件長度來將讀
到字符數組中的內容寫到某個文件中去時,顯然會多寫入一些字符。而這些多
寫入的字符值由于一開始用memset置為0,所以最后在test1.txt文件中就多了
幾個值為0的字符。
????顯然,用fstream類是無法解決這個問題的。因為它沒法返回真正讀到字符
數組中的個數。所以當寫回文件時會多寫入字符。除非在讀文件時判斷有多少
回車換行符,從而在總文件大小中減去這部分值,才是真正讀到字符數組中的
值。所以,解決這個問題只能使用fread函數,因為該函數提供了一個返回參數
來告知真正讀到字符數組中的字符個數(或者使用window提供的API:ReadFile)
該函數也同樣提供了一個返回參數。
????因此,在window下讀出一個文件時,遇到回車換行兩個字符,只會讀入一個
字符:0A。以后在處理時,只能判斷是否是0A來判斷換行,而不能判斷0d來判斷
是否換行。而讀出文件的真正大小需要用fread函數來得知。
????近日寫程序需要讀出文件,對讀出的內容作些修改,再寫回到文件中。
突然發現一個莫名其妙的問題,寫回去的時候居然在文件末尾增加了幾個字
符。感到很不可思議。具體代碼如下:
fstream infile;
????????infile.open("c://test.txt", ios::in);
????????infile.seekp(0, ios::end);
????????int iFileLen = infile.tellp();
????????cout << "File len:" << iFileLen << endl;
????????char * pBuff = new char[iFileLen + 1];
????????memset(pBuff, 0, iFileLen + 1);
????????infile.seekp(0, ios::beg);
????????infile.read(pBuff, iFileLen);
????????infile.close();
????????fstream outfile;
????????outfile.open("c://test1.txt", ios::out|ios::trunc);
????????outfile.write(pBuff, iFileLen);
????????outfile.close();
????????delete[] pBuff;
????在文件test.txt中輸入一個字符'.'以及一個回車鍵,用UE打開,發現該
文件有三個字符,十六進制表示如下:2E 0D 0A。而在屏幕中打印出來的文件
大小也是3??墒俏募est1.txt文件大小卻變成了4,其十六進制表示變成了:
2E 0D 0A 00。莫名其妙的多了一個字節??墒敲髅鲗懭氲淖止潝祽撌?啊。
怎么寫到文件中去卻變成了4了呢?很奇怪的問題。難道是write的問題?于是
我換了一種寫文件方式,改成下面的方式:
????????for(int i = 0; i < iFileLen; i++)
?????????? outfile << pBuff[i];
但是結果仍然同上,仍然多了一個字節。于是感到可能是fstream這個類的問
題,以前也發覺該類在使用seekp時會出錯。于是改成用c語言的文件流讀寫
操作,具體實現如下:
?????? FILE * f = fopen("c://test.txt", "r");
fseek(f, 0, SEEK_END);
int len = ftell(f);
printf("the file len: %d /n", len);
fseek(f, 0, SEEK_SET);
????????char??* p = new char[len + 1];
memset(p, 0x00, len + 1);
fread(p, sizeof(char), len, f);
????????fclose(f);
????????f = fopen("c://test1.txt", "w");
????????fwrite(p, sizeof(char), len, f);
????????fclose(f);
????????delete[] p;
????可惜結果仍然沒變。這就比較奇怪了。怎么會出現這種情況呢?明明文件
大小為3,為何寫到另外一個文件中去卻變成了4呢?于是在程序讀出test.txt
文件內容的下一行添加了一條語句:
????????for(int i = 0; i < len; i++)
????????????cout << (int)p[i];
????結果在屏幕上顯示的居然是這個結果:46 10 0。居然沒有把0A輸出。而是
輸出了0。我突然想到fread返回的結果是真正讀到數據p中的長度,于是我又改
變了一下上面的程序,將fread的結果打印出來:
????????cout << fread(p, sizeof(char), len, f) << endl;
結果果然是2,而不是想當然的3。原來在window下,回車換行的兩個字符讀到
一個數組中去時,只會在數組中保存一個字符:0D。但是用feek來計算文件長
度時返回的卻是文件的實際大小,而不是真正讀入到數組中的值。
????于是,采用fstream類來寫入的時候,文件中每多一個回車換行,實際用
read函數讀到字符數組中的個數就減少一個。而前面我仍然用文件長度來將讀
到字符數組中的內容寫到某個文件中去時,顯然會多寫入一些字符。而這些多
寫入的字符值由于一開始用memset置為0,所以最后在test1.txt文件中就多了
幾個值為0的字符。
????顯然,用fstream類是無法解決這個問題的。因為它沒法返回真正讀到字符
數組中的個數。所以當寫回文件時會多寫入字符。除非在讀文件時判斷有多少
回車換行符,從而在總文件大小中減去這部分值,才是真正讀到字符數組中的
值。所以,解決這個問題只能使用fread函數,因為該函數提供了一個返回參數
來告知真正讀到字符數組中的字符個數(或者使用window提供的API:ReadFile)
該函數也同樣提供了一個返回參數。
????因此,在window下讀出一個文件時,遇到回車換行兩個字符,只會讀入一個
字符:0A。以后在處理時,只能判斷是否是0A來判斷換行,而不能判斷0d來判斷
是否換行。而讀出文件的真正大小需要用fread函數來得知。
總結
以上是生活随笔為你收集整理的一个有关fstream类的bug的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聚类技术---复杂网络社团检测_自然场景
- 下一篇: 你的秘密我能说吗?