一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

ofstream與ate的故事

 wangcqqj123 2017-02-05

很久之前,我和Swalky在寫HuffmanTree壓縮的時(shí)候,遇到了一個(gè)問(wèn)題:我們想在一個(gè)已經(jīng)寫入了一些內(nèi)容的文件中部(或頭部)寫一些內(nèi)容(用于修改文件的一些meta信息),結(jié)果發(fā)現(xiàn)總是不行。如果用ofstream的默認(rèn)構(gòu)造函數(shù),文件原有內(nèi)容就不會(huì)保留下來(lái),如果用了ios::app,無(wú)論怎么用seekp來(lái)定位,所寫的內(nèi)容都會(huì)跟在文件原有內(nèi)容的最后面。怎么辦呢?

本著RTFM的心態(tài),他去看C++ Primer,我則去看TCPL,以及網(wǎng)上的C++ Reference( http://www./reference/ ):

mode
Flags describing the requested i/o mode for thefile. This is an object of type ios_base::openmode, which consists on acombination of one or more of the following flags defined as memberconstants:
flag valueopening mode
app(append) Set the stream's position indicator to the end of the stream before each output operation.
ate(at end) Set the stream's position indicator to the end of the stream on opening.
binary(binary) Consider stream as binary rather than text.
in(input) Allow input operations on the stream.
out(output) Allow output operations on the stream.
trunc(truncate) Any current content is discarded, assuming a length of zero on opening.

我們注意到一個(gè)重要的區(qū)別:app會(huì)在每次寫操作之前都把寫指針置于文件末尾,而ate模式則只在打開(kāi)時(shí)才將寫指針置于文件末尾。于是我們非常興奮地將ofstream置于ios::ate,結(jié)果發(fā)現(xiàn)seekp仍然不能正常工作。

于是我把TCPL的《流》一章反復(fù)讀了幾遍,尤其很認(rèn)真地看了流的緩沖區(qū)streambuf的實(shí)現(xiàn),我突然意識(shí)到,如果不賦予流讀文件的能力,沒(méi)有讀的緩沖區(qū),流就無(wú)法seekp到文件的中部。

我試著改用這段代碼來(lái)構(gòu)造流:

 

Cpp代碼  收藏代碼
  1. fstream(filename, ios::in|ios::out|ios::ate)  
fstream(filename, ios::in|ios::out|ios::ate)
 

 

程序的運(yùn)行成功了!我很興奮,因?yàn)楫?dāng)時(shí)是通過(guò)對(duì)流的實(shí)現(xiàn)的分析推斷出這個(gè)結(jié)論的。

后來(lái)有一次有人在群上問(wèn)C中如何這么做,我經(jīng)過(guò)一番實(shí)驗(yàn),發(fā)現(xiàn)只有以r+模式打開(kāi)文件,fseek才起作用。這其實(shí)仍是基于同樣的原理。這里把C的fopen文檔貼出來(lái):

mode
C string containing a file access modes. It can be:
'r'Open a file for reading. The file must exist.
'w'Create an empty file for writing. If a file withthe same name already exists its content is erased and the file istreated as a new empty file.
'a'Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist.
'r+'Open a file for update both reading and writing. The file must exist.
'w+'Create an empty file for both reading and writing.If a file with the same name already exists its content is erased andthe file is treated as a new empty file.
'a+'Open a file for reading and appending. All writingoperations are performed at the end of the file, protecting theprevious content to be overwritten. You can reposition (fseek, rewind)the internal pointer to anywhere in the file for reading, but writingoperations will move it back to the end of file. The file is created ifit does not exist

r+的意思是同時(shí)讀寫,而且該文件必須已經(jīng)存在。用w+是錯(cuò)誤的,因?yàn)樗鼤?huì)把現(xiàn)存文件的所有內(nèi)容清空。

最后附上當(dāng)時(shí)的測(cè)試代碼(用一個(gè)宏開(kāi)關(guān)來(lái)分別測(cè)試C和C++):

 

Cpp代碼  收藏代碼
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.   
  6. using namespace std;  
  7.   
  8. int main()  
  9. {  
  10.     const char * original = '012345678901234567890123456789'//30 chars  
  11.     const char * overwrite = 'abcdeabcde';  
  12.     const char * filename = 'test.txt';  
  13.   
  14.     fstream fout;  
  15.   
  16.     fout.open(filename, ios::out|ios::trunc); //destroy any current content  
  17.   
  18.     fout <>
  19.   
  20.     fout.close();  
  21.   
  22. #define TESTING_CPP 1  
  23. #if TESTING_CPP  
  24.     fout.open(filename, ios::in|ios::out|ios::ate);  
  25.   
  26.     fout.seekp(7);  
  27.   
  28.     fout <>
  29.     fout.close();  
  30. #else  
  31.     FILE * fout_c;  
  32.   
  33.     if(fout_c = fopen(filename, 'r+'))  
  34.     {  
  35.         fseek(fout_c, 7, SEEK_SET);  
  36.         fprintf(fout_c, overwrite);  
  37.         fclose(fout_c);  
  38.     }  
  39. #endif //TESTING_CPP  
  40.   
  41.     fout.open(filename, ios::in);  
  42.   
  43.     while(!fout.eof())  
  44.     {  
  45.         cout <>static_castchar>(fout.get());  
  46.     }  
  47.   
  48.     return 0;  
  49. }  
#include #include #include #include using namespace std;int main(){ const char * original = '012345678901234567890123456789'; //30 chars const char * overwrite = 'abcdeabcde'; const char * filename = 'test.txt'; fstream fout; fout.open(filename, ios::out|ios::trunc); //destroy any current content fout < original;="" fout.close();#define="" testing_cpp="" 1#if="" testing_cpp="" fout.open(filename,="" ios::in|ios::out|ios::ate);="" fout.seekp(7);="" fout="">< overwrite;="" fout.close();#else="" file="" *="" fout_c;="" if(fout_c="fopen(filename," 'r+'))="" {="" fseek(fout_c,="" 7,="" seek_set);="" fprintf(fout_c,="" overwrite);="" fclose(fout_c);="" }#endif="" testing_cpp="" fout.open(filename,="" ios::in);="" while(!fout.eof())="" {="" cout=""><>(fout.get()); } return 0;}
 

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    在线观看免费无遮挡大尺度视频| 欧美性高清一区二区三区视频| 手机在线观看亚洲中文字幕| 精品少妇人妻一区二区三区| 91日韩欧美中文字幕| 好吊日在线观看免费视频| 欧美日韩国产成人高潮| 精品丝袜一区二区三区性色| 亚洲欧美日本视频一区二区| 一级片二级片欧美日韩| 国产内射一级一片内射高清视频| 免费黄片视频美女一区| 久草热视频这里只有精品| 肥白女人日韩中文视频| 日本在线不卡高清欧美| 中文字幕免费观看亚洲视频| 国产性情片一区二区三区| 亚洲一二三四区免费视频| 亚洲中文字幕视频一区二区| 日韩精品在线观看一区| 色涩一区二区三区四区| 青青操精品视频在线观看| 中文字幕欧美精品人妻一区| 激情亚洲一区国产精品久久| 香港国产三级久久精品三级| 欧美日韩校园春色激情偷拍 | 国产精品成人一区二区三区夜夜夜 | 亚洲最新中文字幕在线视频| 青草草在线视频免费视频| 国产一级二级三级观看| 日韩欧美91在线视频| 国产av一区二区三区麻豆| 国产日韩欧美在线播放| 日韩精品你懂的在线观看| 国产欧美精品对白性色| 青青久久亚洲婷婷中文网| 精品久久少妇激情视频| 久久久精品区二区三区| 丰满少妇被猛烈撞击在线视频| 国产欧美一区二区久久| 国产精品一区二区三区激情|