一个有关fstream类的bug
生活随笔
收集整理的這篇文章主要介紹了
一个有关fstream类的bug
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一個(gè)有關(guān)fstream類的bug
????近日寫程序需要讀出文件,對(duì)讀出的內(nèi)容作些修改,再寫回到文件中。
突然發(fā)現(xiàn)一個(gè)莫名其妙的問題,寫回去的時(shí)候居然在文件末尾增加了幾個(gè)字
符。感到很不可思議。具體代碼如下:
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中輸入一個(gè)字符'.'以及一個(gè)回車鍵,用UE打開,發(fā)現(xiàn)該
文件有三個(gè)字符,十六進(jìn)制表示如下:2E 0D 0A。而在屏幕中打印出來的文件
大小也是3。可是文件test1.txt文件大小卻變成了4,其十六進(jìn)制表示變成了:
2E 0D 0A 00。莫名其妙的多了一個(gè)字節(jié)。可是明明寫入的字節(jié)數(shù)應(yīng)該是3啊。
怎么寫到文件中去卻變成了4了呢?很奇怪的問題。難道是write的問題?于是
我換了一種寫文件方式,改成下面的方式:
????????for(int i = 0; i < iFileLen; i++)
?????????? outfile << pBuff[i];
但是結(jié)果仍然同上,仍然多了一個(gè)字節(jié)。于是感到可能是fstream這個(gè)類的問
題,以前也發(fā)覺該類在使用seekp時(shí)會(huì)出錯(cuò)。于是改成用c語(yǔ)言的文件流讀寫
操作,具體實(shí)現(xiàn)如下:
?????? 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;
????可惜結(jié)果仍然沒變。這就比較奇怪了。怎么會(huì)出現(xiàn)這種情況呢?明明文件
大小為3,為何寫到另外一個(gè)文件中去卻變成了4呢?于是在程序讀出test.txt
文件內(nèi)容的下一行添加了一條語(yǔ)句:
????????for(int i = 0; i < len; i++)
????????????cout << (int)p[i];
????結(jié)果在屏幕上顯示的居然是這個(gè)結(jié)果:46 10 0。居然沒有把0A輸出。而是
輸出了0。我突然想到fread返回的結(jié)果是真正讀到數(shù)據(jù)p中的長(zhǎng)度,于是我又改
變了一下上面的程序,將fread的結(jié)果打印出來:
????????cout << fread(p, sizeof(char), len, f) << endl;
結(jié)果果然是2,而不是想當(dāng)然的3。原來在window下,回車換行的兩個(gè)字符讀到
一個(gè)數(shù)組中去時(shí),只會(huì)在數(shù)組中保存一個(gè)字符:0D。但是用feek來計(jì)算文件長(zhǎng)
度時(shí)返回的卻是文件的實(shí)際大小,而不是真正讀入到數(shù)組中的值。
????于是,采用fstream類來寫入的時(shí)候,文件中每多一個(gè)回車換行,實(shí)際用
read函數(shù)讀到字符數(shù)組中的個(gè)數(shù)就減少一個(gè)。而前面我仍然用文件長(zhǎng)度來將讀
到字符數(shù)組中的內(nèi)容寫到某個(gè)文件中去時(shí),顯然會(huì)多寫入一些字符。而這些多
寫入的字符值由于一開始用memset置為0,所以最后在test1.txt文件中就多了
幾個(gè)值為0的字符。
????顯然,用fstream類是無法解決這個(gè)問題的。因?yàn)樗鼪]法返回真正讀到字符
數(shù)組中的個(gè)數(shù)。所以當(dāng)寫回文件時(shí)會(huì)多寫入字符。除非在讀文件時(shí)判斷有多少
回車換行符,從而在總文件大小中減去這部分值,才是真正讀到字符數(shù)組中的
值。所以,解決這個(gè)問題只能使用fread函數(shù),因?yàn)樵摵瘮?shù)提供了一個(gè)返回參數(shù)
來告知真正讀到字符數(shù)組中的字符個(gè)數(shù)(或者使用window提供的API:ReadFile)
該函數(shù)也同樣提供了一個(gè)返回參數(shù)。
????因此,在window下讀出一個(gè)文件時(shí),遇到回車換行兩個(gè)字符,只會(huì)讀入一個(gè)
字符:0A。以后在處理時(shí),只能判斷是否是0A來判斷換行,而不能判斷0d來判斷
是否換行。而讀出文件的真正大小需要用fread函數(shù)來得知。
????近日寫程序需要讀出文件,對(duì)讀出的內(nèi)容作些修改,再寫回到文件中。
突然發(fā)現(xiàn)一個(gè)莫名其妙的問題,寫回去的時(shí)候居然在文件末尾增加了幾個(gè)字
符。感到很不可思議。具體代碼如下:
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中輸入一個(gè)字符'.'以及一個(gè)回車鍵,用UE打開,發(fā)現(xiàn)該
文件有三個(gè)字符,十六進(jìn)制表示如下:2E 0D 0A。而在屏幕中打印出來的文件
大小也是3。可是文件test1.txt文件大小卻變成了4,其十六進(jìn)制表示變成了:
2E 0D 0A 00。莫名其妙的多了一個(gè)字節(jié)。可是明明寫入的字節(jié)數(shù)應(yīng)該是3啊。
怎么寫到文件中去卻變成了4了呢?很奇怪的問題。難道是write的問題?于是
我換了一種寫文件方式,改成下面的方式:
????????for(int i = 0; i < iFileLen; i++)
?????????? outfile << pBuff[i];
但是結(jié)果仍然同上,仍然多了一個(gè)字節(jié)。于是感到可能是fstream這個(gè)類的問
題,以前也發(fā)覺該類在使用seekp時(shí)會(huì)出錯(cuò)。于是改成用c語(yǔ)言的文件流讀寫
操作,具體實(shí)現(xiàn)如下:
?????? 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;
????可惜結(jié)果仍然沒變。這就比較奇怪了。怎么會(huì)出現(xiàn)這種情況呢?明明文件
大小為3,為何寫到另外一個(gè)文件中去卻變成了4呢?于是在程序讀出test.txt
文件內(nèi)容的下一行添加了一條語(yǔ)句:
????????for(int i = 0; i < len; i++)
????????????cout << (int)p[i];
????結(jié)果在屏幕上顯示的居然是這個(gè)結(jié)果:46 10 0。居然沒有把0A輸出。而是
輸出了0。我突然想到fread返回的結(jié)果是真正讀到數(shù)據(jù)p中的長(zhǎng)度,于是我又改
變了一下上面的程序,將fread的結(jié)果打印出來:
????????cout << fread(p, sizeof(char), len, f) << endl;
結(jié)果果然是2,而不是想當(dāng)然的3。原來在window下,回車換行的兩個(gè)字符讀到
一個(gè)數(shù)組中去時(shí),只會(huì)在數(shù)組中保存一個(gè)字符:0D。但是用feek來計(jì)算文件長(zhǎng)
度時(shí)返回的卻是文件的實(shí)際大小,而不是真正讀入到數(shù)組中的值。
????于是,采用fstream類來寫入的時(shí)候,文件中每多一個(gè)回車換行,實(shí)際用
read函數(shù)讀到字符數(shù)組中的個(gè)數(shù)就減少一個(gè)。而前面我仍然用文件長(zhǎng)度來將讀
到字符數(shù)組中的內(nèi)容寫到某個(gè)文件中去時(shí),顯然會(huì)多寫入一些字符。而這些多
寫入的字符值由于一開始用memset置為0,所以最后在test1.txt文件中就多了
幾個(gè)值為0的字符。
????顯然,用fstream類是無法解決這個(gè)問題的。因?yàn)樗鼪]法返回真正讀到字符
數(shù)組中的個(gè)數(shù)。所以當(dāng)寫回文件時(shí)會(huì)多寫入字符。除非在讀文件時(shí)判斷有多少
回車換行符,從而在總文件大小中減去這部分值,才是真正讀到字符數(shù)組中的
值。所以,解決這個(gè)問題只能使用fread函數(shù),因?yàn)樵摵瘮?shù)提供了一個(gè)返回參數(shù)
來告知真正讀到字符數(shù)組中的字符個(gè)數(shù)(或者使用window提供的API:ReadFile)
該函數(shù)也同樣提供了一個(gè)返回參數(shù)。
????因此,在window下讀出一個(gè)文件時(shí),遇到回車換行兩個(gè)字符,只會(huì)讀入一個(gè)
字符:0A。以后在處理時(shí),只能判斷是否是0A來判斷換行,而不能判斷0d來判斷
是否換行。而讀出文件的真正大小需要用fread函數(shù)來得知。
總結(jié)
以上是生活随笔為你收集整理的一个有关fstream类的bug的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聚类技术---复杂网络社团检测_自然场景
- 下一篇: C++书藉大全