C/C++輸入輸出資料流總結
前兩天寫C++實習作業,突然發現I/O是那麼的陌生,打了好長時間的檔案都沒有開啟,今天終於有點時間了,決定找本書,好好整理一下,和大家共用。
C++ I/O
C++支援兩種I/O,第一種是從C語言繼承來的,一種是由C++定義的物件導向I/O系統。
1、int getchar(void);返回一個整數值,也可以指定這個值為char變數,因為這個字元包含於低位位元組中(高位位元組通常為0),如果有錯,getchar()返回EOF。但是他有一個潛在的問題,正常情況下,getchar()緩衝輸入,直到鍵入了斷行符號鍵(這個大家應該深有體會,就是getchar()貌似只認識斷行符號鍵,原來是這個原因)這稱為行緩衝輸入,在鍵入的字元實際傳送給程式之前必須敲入一個斷行符號鍵。
2、int putchar(int c);
雖然putchar()帶一個整數參數,通常可以用一個字元的變元調用它,但是只有其低位位元組被實際輸出到螢幕上,putchar()函數放回被寫入的字元,若操作失敗,返回EOF(宏EOF被定義於stdio.h中,通常其值為-1)。
3、int getch(void);
int getche(void);
兩個最常用的互動式函數,對於大多數編譯器,這些函數的原型都可在標頭檔conio.h中找到,對於某些編譯器中這些函數前面有一底線。如_getch()和_getche();這就是為什麼在VS2008中經常提示要在前面加一個'_'.
4、char* gets(char* str);
讀取從鍵盤上輸入的字串並把它存放在由其他變元所指的地址中,它從鍵盤讀入字元,直到遇到斷行符號鍵為止。斷行符號鍵不輸入串的一部分,相反,將空結束符放在串尾來代替,並且由gets()返回。但是使用gets()是要小心,因為它不對正在接受輸入的字元數組執行邊界檢查。因此,使用者可以鍵入比數組能夠容納的更多的字元。儘管對於你使用的範常式序和簡單使用工具是很好的,在商用代碼中一般不是用它。它的的替代物是fgets();稍後描述。
5、int puts(const char* str);
將它的字串變元寫到螢幕上,後跟一新行。它的調用比printf();開銷小,因為puts()只能輸入字串,不能輸出數字或進行格式轉換,因而puts()用的空間少且速度比printf()快。因此函數puts()經常用於代碼最佳化,操作失敗,函數puts()返回EOF,否則返回非負值。
6、int printf(const char* control_string,...);
printf()函數返回寫入字元的數目,如果出現一個錯誤,則返回control_string(控制串)有兩種類型項目組成。第一類由將列印在螢幕上的字串組成,第二類包括自訂其後變元顯示方式的格式限定符。格式限定符以一個百分比符號開頭,後跟格式化碼,變元列表中的變元數與格式限定符完全相等,格式限定符與變元按順序從左至右匹配。
7、int scanf(const char* control_string...);
可以讀入各種內嵌類型並自動將其轉換為適當的格式。返回成功的賦予了一個值的資料項目。如果出現一個錯誤,scanf()返回EOF。控制串包括三類字元:
a、格式限定符 b、空白字元 c、非空白字元
格式限定符以百分比符號開始,告訴scanf()下一步要讀的資料是什麼類型。
8、FILE* fopen(const char*filename,const*char* mode)
開啟一個檔案
mode合法值如下:
r 為讀操作開啟一個文字檔
w 為寫操作建立一個文字檔
a 附加到一個文字檔
rb 為讀操作開啟一個二進位檔案
wb 為寫操作建立一個二進位檔案
ab 附加到一個二進位檔案
r+ 為讀/寫操作開啟一個文字檔
w+ 為讀/寫操作建立一個文字檔
a+ 為讀/寫操作附加或建立一個文字檔
r+b 為讀/寫操作開啟一個二進位檔案
w+b 為讀/寫操作建立一個二進位檔案
a+b 為讀/寫操作附加一個二進位檔案
如果開啟檔案失敗,fopen()返回一個null 指標。
9、int fclose(FILE* fp);
關閉一個由fopen()開啟的檔案,把留在磁碟緩衝區的資料寫入檔案並在作業系統級正式關閉檔案。關閉流檔案失敗會產生各種麻煩,如:遺失資料,破壞檔案和程式中出現間歇的錯誤等。flose()也釋放與流檔案控制區,使它可以重用。有時,由於作業系統一次同時開啟的檔案數量有限,因此必須在關閉一個檔案後再開啟另一個檔案。 返回0標誌著檔案關閉成功。如果關閉失敗,則返回EOF。可用標準函數ferror()來確定和報告出錯訊息。通常,fclose()僅在磁碟中磁碟機中過早移走或磁碟上沒有更多的空間時報錯。
10、int putc(int ch,FILE* fp);
把一個字元寫到檔案中,如果操作成功,則函數返回被輸出的位元組;否則,返回EOF
11、int getc(FILE* fp);
從某一檔案讀一個字元,函數getc()讀到檔案尾時返回EOF標誌,如果發生錯誤,也返回EOF。
12、fgetc(),同getc()
13、int fgets(const char*str,int length,FILE* fp);從某一檔案中讀取一個字串,直到讀到分行符號或讀完length-1個字元,如果讀到新行,它是原字串的一部分(不像gets()那樣另起新串),結果字串將以NULL終止。如果操作成功,則函數返回str,否則返回null 指標。
14、int fputs(const char*str,FILE*fp),把str指向的字串寫到指定的流中,如果失敗,則返回EOF
15、fseek(),在檔案中尋找一個特定的位元組
16、ftell(),返回當前檔案的位置
17、fprintf(),輸出到磁碟檔案上
18、fscanf(),從磁碟中讀資料
19、int feof(FILE* fp);
若到檔案尾,返回真值.既可用於二進位檔案,也可應用於文字檔
eg:
while(!feof(fp)) ch = getc(fp);
20、int ferror(FILE* fp);
函數確定是否在檔案操作期間出錯。fp是有效檔案指標。在檔案操作期間如果有錯,則函數返回true,否則返回false。由於每個檔案操作均設定錯誤條件,因而應在每個檔案中操作後立即調用ferror(),否則會丟失錯誤資訊。
21、void rewind(FILE* fp),把檔案位置指標重新置於檔案的起始位置,fp是有效檔案指標,
22、int remove(const char*filename),清除一個檔案,操作成功,返回0,操作失敗返回非零值。
23、int fflush(FILE* fp);
清空一個輸出資料流的內容,將任何緩衝區的內容寫到與fp相關的檔案中,如果在fp為空白時調用fflush(),則所有為輸出開啟的檔案被清空。操作成功返回0,否則返回EOF。
24,size_t fread(void* buffer,size_t num_byte,size_t count,FILE* fp);
buffer 是一個指標,指向一個接收檔案中資料的儲存區,count的值指出要寫多少項。返回讀入的項的數目,如遇到檔案的結尾或操作失敗。這個值可能少於count。
25、size_t fwrite(const void * buffer,size_t num_byte,size_t count ,FILE* fp);
buffer 是一個指標,指向要寫入檔案中的資訊快。count的值指出要寫多少項。返回寫入項的數目,這個值永遠等於count,除非操作失敗。
注意:size_t類型被定義為某種不帶正負號的整數,fp是一個指向已經開啟流的檔案指標。fwrite()和fread()最大的用途之一是可以寫使用者自訂的資料類型,特別是結構體類型
26、int fseek(FILE* fp,long int numbytes,int origin);
fp是由fopen()返回的指標,numbytes是從檔案的origin位置到當前位置的位元組,是下面的宏之一:
origin 宏名
檔案開始處 SEEK_SET
當前位置 SEEK_CUR
檔案末尾 SEEK_END
可以用fseek()來尋找任何資料類型的倍數,方法是用想要的項數乘以資料的長度。eg:fseek(fp,9*sizeof(struct myStruct),SEEK_SET);
27、long int ftell(FILE* fp);
決定一個檔案的當前位置,返回與fp關聯的檔案的當前位置的地址。如果失敗,返回-1.
28、int fprintf(FILE* fp,const char* control_string...);
int fscanf(FILE* fp,const char* control_string...);
注意:儘管fprintf()和scanf()是從磁碟檔案中讀寫資料最容易的方法,但卻並不是最有效方法。由于格式化的ASCⅡ資料寫入檔案的格式與在螢幕上顯示的相同(而不是二進位方式),因而調用時要引起額外的開銷。如果要考慮速度與檔案長度,最好使用fread()和fwrite()
C++內建流
流 含義 預設裝置
cin 標準輸入 鍵盤
cout 標準輸出 螢幕
cerr 標準錯誤輸出 螢幕
clog cerr的緩衝版本 螢幕
cin、cout、cerr和C的stdin、stdout、stderr相對應。
C++附加流:win、wout、werr、wlog它們都是款字元版本的標準流,寬字元類型為wchar_t,一般為16位。
29、fmtflags setf(fmtflags flags);
該函數返回格式標記先前的並開啟又flags指定的那些標記。
eg:
cout.setf(ios::showpoint);
cout.setf(ios::showpos);
或者cout.setf(ios::showpoint | ios::showpos);
30、void unsetf(fmtflags flags);
flags指定的標記被清除
eg:
cout.setf(ios::uppercase | ios::scientfic);
cout.unsetf(ios::uppercase);
31、fmtflags flags();
返回每個格式標記的當前位置。
32、fmtflags flags(fmtflags f);
設定某個流的所有標記。
eg:
ios::fmtflags f = ios::showpos | ios::showbase | ios::oct | ios::right;
cout.flags(f);//set all flags
33、streamsize width(streamsize w);
修改最小域寬,w是將要改成的域寬,先前的域寬返回。
34、streamsize precision(streamsize p);
當輸出浮點型時,可以使用precision()函數來確定數位精確位元。
35、char fill(char ch);
填充指定字元,預設情況下是空格
C++操作運算元
操作運算元 用途 輸入/輸出
boolapha 開啟boolapha標記 輸入/輸出
dec 開啟dec標記 輸出
endl 輸出一個分行符號並重新整理流 輸出
ends 輸出一個null 輸出
fixed 開啟fixed標記 輸出
flush 重新整理一個流 輸出
hex 開啟hex標記 輸出/輸入
internal 開啟internal標記 輸出
left 開啟left標記 輸出
noboolalpha 關閉noboolalpha標記 輸入/輸出
noshowbase 關閉showbase標記 輸出
noshowpoint 關閉showpoint標記 輸出
noshowpos 關閉showpos標記 輸出
noskipws 關閉skipws標記 輸入
nounitbuf 關閉unitbuf標記 輸出
nouppercase 關閉uppercase標記 輸出
oct 開啟oct標記 輸入/輸出
resetiosflags(fmtflags f) 關閉f中指定的標記 輸入/輸出
right 開啟right標記 輸出
scientific 開啟scientific標記 輸出
setbase(int base) 將基數設為base 輸入/輸出
setfill(int ch) 將填充字元設定為ch 輸出
setiosflags(fmtflags f)開啟f中指定的標記 輸入/輸出
setprecision(int p) 設定字元精度 輸出
setw(int w) 將域寬設定為w 輸出
showbase 開啟showbase標記 輸出
showpoint 開啟showpoint標記 輸出
showpos 開啟showpos標記 輸出
skipws 開啟skipws標記 輸入
unitbuf 開啟unitbuf標記 輸出
uppercase 開啟uppercase標記 輸出
ws 跳過開始的空格 輸入
注意:在訪問帶參數的操運算元,必須在程式中包括<iomanip>
建立自己的插入器:
ostream& operator<<(ostream& stream,class_type obj)
{
//body of inserter
return stream;
}
建立自己的析取器
istream& operator>>(istream& stream,class_type obj)
{
//body of extractor
return stream;
}
C++檔案的輸入和輸出<fstream>
建立一個流
ifstream in;//input
ofstream out;//output
fstream io;//input and output
36、
void ifstream::open(const char*filename,ios::opennode mode = ios::in);
void ofstream::open(const char*filename,ios::openmode mode = ios::out | ios::trunc);
void fstream::open(const char* filename,ios::openmode mode = ios::in | ios::out);
openmode:
ios::app 使所有輸出到相應檔案的內容都添加到檔案末尾,該值只能用於具有輸出功能的檔案。
ios::ate 使得在開啟檔案時能夠定位到檔案末尾
ios::binary 可以以二進位檔案開啟,預設情況下,所有檔案都以文本方式開啟。
ios::in 指定為輸入
ios::out 制定我輸出
ios::trunc 銷毀具有相同名字的先前檔案的內容,並且將檔案長度截斷為0,當使用ofstream建立一個輸出資料流時任何先前存在的具有該檔案名稱的檔案將被自動截斷
eg:
if(!mystream)
{
cout<<"Cannot open file.\n";
//handdle error
}
if(!mystream.is_open())
{
cout<<"Cannot open file.\n";
//handdle error
}
37、istream &get(char &ch);
ostream &put(char &ch);
eg:
while(in.get(ch))
cout<<ch;
38、istream& read(char* buf,streamsize num);
ostream& write(const char* buf,streamsize num);
read()函數從流中讀取num字元並將他們放入由buf所指的緩衝區。write()函數把num字元從buf所指的緩衝區寫入調用流,streamsize是由C++庫定義的類型--是某種類型,它可以儲存能夠被任何一種I/O操作轉換的最大字元數。
39、streamsize gcount();
檢查已經有多少字元被讀取
40、get()的重載版本:
istream& get(char* buf,streamsize num);
把字元讀入由buf指向的數組,直到讀取到第num-1個字元,發現了一個分行符號或者遇到了檔案尾。指標buf所指向的數組以null字元結束。
istream& get(char* buf,streamsize num,char delim);
把字元讀入由buf指向的數組,直到讀取到第num-1個字元,發現了由delim指定的字元或者是遇到了檔案尾。指標buf所指向的數組以null字元結束。如果在輸入資料流中遇到分隔字元字元,則不會提取該字元。
int get();
返回相應流的下一個字元,如果遇到檔案尾,則返回EOF。get()函數的這種形式類似於C的函數
41、istream& getline(char* buf,streamsize num);
把字元讀入由buf指向的數組,直到讀取到第num-1個字元,發現了一個分行符號或者遇到了檔案尾。指標buf所指向的數組以null字元結束。如果在出輸入資料流中遇到分行符號是,則提取該字元,但是不會將其放入buf
istream& getline(char* buf,streamsize num,char delim);
把字元讀入由buf指向的數組,直到讀取到第num-1個字元,發現了由delim指定的字元或者是遇到了檔案尾。指標buf所指向的數組以null字元結束。如果在輸入資料流中遇到分隔字元字元,則提取該字元,但是不將其放入buf
42、bool eof();
到達檔案尾時,該函數返回true,否則返回false
43、istream & ignore(streamsize num = 1,int_type delim = EOF);
該函數讀取和放棄字元,直到num個字元被忽略(預設值為1)或者遇到delim指定為字元(預設值為EOF)
44、int_type peek();
返迴流中的下一個字元,如果遇到檔案尾,則返回EOF(int_type 被定義為某種整數型類型)
45、istream& putback(char c);
返迴流中的最後一個字元,c是讀取最後一個字元
46、ostream& flush();
在緩衝區被寫滿資料前強行將資料寫到磁碟
47、istream& seekg(off_type offset,seekdir origin);
ostream& seekp(off_type offset,seekdir origin);
off_type是ios定義的一個整數類型,可以包含offset具有的最大有效值,seekdir是一個ios定義的枚舉類型,用來決定尋找方式。seekg()函數可以把相關檔案當前的擷取指標從指定origin出位移offset個字元,origin必須是一下三個值中的一個
ios::beg 檔案頭
ios::cur 當前位置
ios::end 檔案尾
seekp()函數可以把相關檔案當前的擷取指標從指定origin出位移offset個字元,origin必須是以上三個值之一
48、pos_type tellg();
pos_type tellp();
確定每一個檔案指標的位置。pos_type是ios定義的類型,它儲存函數可以返回最大值。
I/O狀態:儲存在一個iostate類型的對象中,它是ios定義的枚舉類型,包括一下成員:
ios::goodbit 無錯誤位設定
ios::eofbit 當遇到檔案尾時為1;否則為0
ios::failbit 當出現非致命錯誤時為1,否則為0
ios::badbit 當出現致命的I/O錯誤時為1;否則為0
獲得I/O狀體的方法:
a、iostate rdstate();
b、bool bad();
bool eof();
bool fail();
bool good();
一旦出現錯誤,或許在程式繼續運行之前需要清除該錯誤,為此,可以使用clear()函數
void clear(iostate flags = ios::goodbit);
參考資料:《C++參考大全(第四版)》
本文完
轉載請表明出處,謝謝
2010-08-19