詳解C語言輸入/輸出函數(shù)

錯誤報告

perror函數(shù)簡化向用戶報告特定錯誤的過程。它的原型定義于studio.h,如下:

  void perror(char const *message);

如果message不是NULL并且指向一個非空的字符串舞吭,perror函數(shù)就打印出這個字符串镀梭,后面跟一個分號和一個空格餐曼,然后打印出一條用于解釋errno(標準庫函數(shù)用一個外部整型變量來保存錯誤碼)。

終止執(zhí)行

exit函數(shù)用來終止一個程序,它的原型定義于stdlib.h,如下:

  void exit(int status);

status參數(shù)返回給操作系統(tǒng)颓鲜,用于提示程序是否正常完成孽水。這個值和main函數(shù)返回的整型狀態(tài)值一樣,預(yù)定義符號EXIT_SUCCESS和EXIT_FALIURE分別提示程序的終止成功還是失敗匣屡,雖然程序可以使用其他值封救,但它們的具體含義取決于編譯器。

注意這個函數(shù)沒有返回值耸采。當(dāng)exit函數(shù)結(jié)束時兴泥,程序已經(jīng)消失,所以它無處可返虾宇。

標準I/O函數(shù)庫

頭文件stdio.h包含了與ANSI函數(shù)庫的I/O部分有關(guān)的聲明搓彻。

就C程序而言,所有的I/O操作只是簡單地從程序移進移出字節(jié)的事情,這些字節(jié)流便被稱為旭贬。

流I/O總覽

I/O函數(shù)以三種基本的形式處理數(shù)據(jù):單個字符,文本行和二進制數(shù)據(jù)對于每一種都有特定的函數(shù)對他們進行處理稀轨。
??????????????????執(zhí)行字符奋刽,文本行和二進制I/O的函數(shù)

數(shù)據(jù)類型 輸 入 輸 出 描 述
字符 getchar putchar 讀扔缎场(寫入)單個字符
文本行 gets puts 文本行未格式化的輸入(輸出)
文本行 scanf printf 格式化的輸入(輸出)
二進制數(shù)據(jù) fread fwrite 讀取(寫入)二進制數(shù)據(jù)

打開流

fopen用于打開一個特定的文件罚攀,并把一個流和這個文件相關(guān)聯(lián)斋泄,它的原型如下:

File *fopen(char const *name,char const *mode);

參數(shù)name是打開的文件名炫掐,mode是打開文件的方式(見下表)任柜,F(xiàn)ile*類型的變量用來保存fopen的返回值宙地,并不影響哪個文件被打開。

數(shù)據(jù)格式 讀 取 寫 入 添 加
文本 "r" "w" "a"
二進制 "rb" "wb" "ab"

如果一個文件打開是用于讀取的参袱,那么他應(yīng)該是原先已經(jīng)存在的抹蚀;
??如果一個文件打開是用于寫入的环壤,那么它原先的內(nèi)容就會被刪除郑现,如果它原先不存在,那么就創(chuàng)建一個新文件接箫;
??如果一個文件打開用于天機的文件原先并不存在那么它將被創(chuàng)建,如果它原先已經(jīng)存在辛友,那么它原先的內(nèi)容不會被刪除,無論那種情況都只能在文件的尾部寫入废累。
??freopen用于打開特定(重新打開)的文件流,它的原型如下:

File *freopen(char const *filename,char const *mode,File *stream);

最后一個參數(shù)就是要打開的流,它可能是一個先前用fopen函數(shù)打開的流震放,也可能是stdin,stdout或是stderr驼修。

關(guān)閉流

int fclose(File *f);

對于輸出流乙各,fclose函數(shù)在文件關(guān)閉前刷新緩沖區(qū)耳峦,如果它執(zhí)行成功焕毫,fclose返回零值邑飒,否則返回EOF疙咸。

字符I/O

字符輸入是由getchar函數(shù)家族執(zhí)行的撒轮,他們的原型如下:

int fgetc(File *stream);
int getc(File *stream);
int getchar(void);

這些函數(shù)都用于讀取字符题山,但它們都返回一個int型但是不是char型。

字符輸出是由putchar函數(shù)家族執(zhí)行的玖姑,它們的原型如下:

int fputc(int character,File *stream);
int putc(int character,File *stream);
int putchar(int character);

fgetc和fputc都是真正的函數(shù)客峭,但getc,putc,getchar,putchar,都是通過宏定義的舔琅。

撤銷字符I/O

函數(shù)原型如下:

int ungetc(int character,File*stream);

函數(shù)ungetc把一個先前讀入的字符返回流中备蚓,這樣它可在以后被重新讀入郊尝。

未格式化的行I/O

行I/O的執(zhí)行方式分為兩類——未格式化或格式化,這兩種形式都用于操作字符串扎即。
gets和puts家族函數(shù)的原型如下:

char *fgets(char *buffer,int buffer_size,File *stream);
char gets(char *buffer);

int fputs(char *buffer,File *stream);
int puts(char const *buffer);

fgets函數(shù)從制定的stream中讀取字符并把它們復(fù)制到buffer中谚鄙,當(dāng)它讀取到一個換行符并存儲到緩沖區(qū)之后就不在讀取闷营。
fgets函數(shù)從制定的流中讀取buffer_size字符和一個NULL字符(尾零)傻盟。
fgets函數(shù)返回它的第一個參數(shù)(執(zhí)行緩沖區(qū)的指針)娘赴,如果在未讀取任何字符就達到文件尾筝闹,fgets返回NULL关顷。
fputs函數(shù)的緩沖區(qū)必須包含一個以NULL結(jié)尾的字符串议双,所以該函數(shù)沒有字符串的長度參數(shù)平痰,這個字符串是逐字寫入的宗雇,如果它不包含一個換行符赔蒲,就不會寫入換行符。如果包含好幾個換行符欢际,所有的換行符都會被寫入损趋。

函數(shù)gets和puts幾乎和函數(shù)fgets和fputs相同浑槽,區(qū)別在于:
1.gets在讀取一行輸入時括荡,它并不在緩沖區(qū)中存儲結(jié)尾的換行符
2.puts在寫入一個字符串時观腊,它在字符串寫入之后向輸出在添加一個換行符梧油。

格式化的I/O

scanf和printf函數(shù)家族負責(zé)格式化行的輸入與輸出儡陨。

scanf家族

scanf函數(shù)家族的原型中的省略號表示一個可變長的指針列表量淌。從輸入轉(zhuǎn)換而來的值逐個存儲到這些指針參數(shù)所指向的內(nèi)存位置胚股。

int fscanf(File *stream,char const *fomat,...);
inr scanf(char const *fomat,...);
int sscanf(char const *string,char const *format,...);

這些函數(shù)都是從輸入源讀取字符并根據(jù)format字符串個出的格式碼對他們進行轉(zhuǎn)換琅拌,fscanf的輸入源就是stream(流)进宝,scanf的輸入源就是stdin党晋,而sscanf則從第一個參數(shù)給出的字符串中讀取字符漏益。

當(dāng)格式化字符串達到末尾或者讀取的輸入不在匹配格式字符串所指定的類型事绰疤,輸入就停止轻庆,在任何一種情況下,被轉(zhuǎn)換的輸入值的數(shù)目作為函數(shù)的返回值蛾方。如果在任何輸入值被轉(zhuǎn)換之前就達到尾部桩砰,函數(shù)就返回常量值EOF

scanf格式代碼

scanf函數(shù)家族中的format字符串可以是下列內(nèi)容:

  • 空白字符——他們與輸入中的零個或多個空白符匹配煮纵,在處理過程中被忽略偏螺。
  • 格式代碼——它們指定函數(shù)如何解釋接下來的輸入字符隘擎。
  • 其他字符——當(dāng)任何其他字符出現(xiàn)在格式字符串中采幌,下一個輸入字符必須與他匹配震桶。如果匹配蹲姐,該輸入字符隨后被丟棄忙厌,如果不匹配逢净,函數(shù)就不在讀取直接返回。

scanf函數(shù)家族的格式字符串通常以一個%號開始,有下列內(nèi)容組成:

  • 可選的星號(*)——將轉(zhuǎn)換后的值丟棄而不是存儲琼娘;
  • 一個可選的寬度——限制輸入字符的個數(shù)轨奄,如果寬度未給出挨务,函數(shù)就連續(xù)輸入知道遇見輸入中的下一個空白字符丁侄;
  • 一個可選的限定符——修改有些格式代碼的含義鸿摇;
  • 格式代碼。

printf函數(shù)家族

printf函數(shù)家族用于創(chuàng)建格式化輸出往史。

int fprintf(File *stream,char const *format,...);
int printf(char connst *format,...);
int sprintf(char *buffer,char const *format,...);

prinnt結(jié)果輸出送到標準輸出(stdout)
fprintf可以使用任何輸出流
sprintf把它的的結(jié)果作為一個NULL結(jié)尾的字符串存儲到指定的buffer緩沖區(qū)刷晋,而不是流;

printf家族函數(shù)的格式碼通常以%開始由下列要素組成:

  • 零個或多個標志字符——修改轉(zhuǎn)換的執(zhí)行方式掏秩;
  • 一個可選的最小字段——如果值的字符小于字段寬度胆筒,就對它進行填充增加長度仆救,標志決定填充使用空白還是零以及它出現(xiàn)在值得左邊還是右邊;
  • 一個可選的精度——指定將出現(xiàn)結(jié)果中的最小的數(shù)字個數(shù)并覆蓋零標志,精度缺省為零征懈;
  • 一個可選的修改字符;
  • 轉(zhuǎn)換類型揩悄;

二進制I/O

??把數(shù)據(jù)寫入到文件效率最高的是二進制形式寫入卖哎。二進制輸出避免了在數(shù)值轉(zhuǎn)換成字符串過程的所涉及的開銷和精度損失。
??fread函數(shù)用于讀取二進制數(shù)據(jù),fwrite函數(shù)用于寫入二進制亏娜,他們的原型如下:

size_t  fread(void *bffer,size_t size,sizet_cout,File *stream);
size_t  fwrite(void *bffer,size_t size,sizet_cout,File *stream);

??buffer是一個指向用于保存數(shù)據(jù)的內(nèi)存位置的數(shù)據(jù)焕窝,size是緩沖區(qū)每個元素的字節(jié)數(shù),count是讀取或?qū)懭氲脑財?shù)照藻,stream是數(shù)據(jù)讀取或?qū)懭氲牧鳌?br> ??函數(shù)的返回值是實際讀取或?qū)懭氲?em>元素數(shù)目袜啃。

刷新或定位函數(shù)

  • 函數(shù)fflush——它迫使一個輸出流的緩沖區(qū)內(nèi)的數(shù)據(jù)進行物理寫入,不管它是否已經(jīng)寫滿幸缕,原型如下:
int fflush(File *stream);

??當(dāng)我們需要立即把數(shù)據(jù)緩沖區(qū)的內(nèi)容吳莉莉?qū)懭霑r群发,就可以使用這個函數(shù)。

C語言支持隨機I/O发乔,也就是以任意的順序訪問文件中的不同位置熟妓,隨機訪問時通過在讀取或?qū)懭肭岸ㄎ坏轿募兴枰奈恢脕韺崿F(xiàn)的,ftell和fseek函數(shù)來實現(xiàn)這項操作栏尚。

long ftell(File *stream);
int fseek(File *stream,long offset,int from);

ftell函數(shù)返回當(dāng)前流的位置起愈,也就是說,下一個讀取或?qū)懭雽⒁_始的位置距離文件起始位置的偏移量译仗。
ftell函數(shù)的返回值總是可以作為函數(shù)fseek的參數(shù)抬虽,作為一個距離文件起始位置的偏移量。
函數(shù)fseek允許你在一個流中定位纵菌,這項操作將改變下一個讀取或?qū)懭氲奈恢貌郏牡诙谌齻€參數(shù)如下表。

數(shù)據(jù)格式 你將定位到的是
SEEK_SET 從流的起始位置起offset個字節(jié)咱圆,offset必須是一個非負值
SEEK_CUR 從流的當(dāng)前位置起offset個字節(jié)笛辟,offset可正可負
SEEK_END 從流的尾部位置起offset個字節(jié),offset可正可負序苏,如果是正直將定位到文件尾的后面

改變緩沖方式

??在流上的緩沖凡是有時候并不適合手幢,下面兩個函數(shù)可以改變流的緩沖方式,這兩個函數(shù)只有當(dāng)指定的流被打開還沒有在它上面執(zhí)行任何操作時才能夠被調(diào)用忱详。

void setbuf(File *stream,char *buf);
int setvbuf(File *stream,char *buf,int mode,size_t size);

setbuf函數(shù)設(shè)置了一個數(shù)組围来,用于對流進行緩沖。這個數(shù)組的長度必須是BUFSIZE(它在stdio中定義)如果以一個NULL參數(shù)調(diào)用這個函數(shù)匈睁,setbuf會將這個流關(guān)閉管钳。
setvbuf函數(shù)中的mode參數(shù)用于指定緩沖類型,_IOFBF指定一個完全緩沖流软舌,_IONBF指定一個不緩沖的流,_IOLBF指定一個行緩沖流(當(dāng)一個換行符寫入到緩沖區(qū)時牛曹,緩沖區(qū)就進行刷新)

文件操縱函數(shù)

??有兩個函數(shù)用于操縱文件但不執(zhí)行任何輸入/輸出操作佛点,執(zhí)行成功函數(shù)返回值為零,如果失敗返回非零。

int remove(char const *filename);
int rename(char const *oldname,char const *newname);

函數(shù)remove用于刪除一個指定的文件呢超营,文件處于打開狀態(tài)鸳玩,其結(jié)果取決于編譯器。
函數(shù)rename用于重命名文件名演闭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末不跟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子米碰,更是在濱河造成了極大的恐慌窝革,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吕座,死亡現(xiàn)場離奇詭異虐译,居然都是意外死亡,警方通過查閱死者的電腦和手機吴趴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門漆诽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锣枝,你說我怎么就攤上這事厢拭。” “怎么了撇叁?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵供鸠,是天一觀的道長。 經(jīng)常有香客問我税朴,道長回季,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任正林,我火速辦了婚禮泡一,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘觅廓。我一直安慰自己鼻忠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布杈绸。 她就那樣靜靜地躺著帖蔓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞳脓。 梳的紋絲不亂的頭發(fā)上塑娇,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音劫侧,去河邊找鬼埋酬。 笑死哨啃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的写妥。 我是一名探鬼主播拳球,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼珍特!你這毒婦竟也來了祝峻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤扎筒,失蹤者是張志新(化名)和其女友劉穎莱找,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砸琅,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡宋距,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了症脂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谚赎。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诱篷,靈堂內(nèi)的尸體忽然破棺而出壶唤,到底是詐尸還是另有隱情,我是刑警寧澤棕所,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布闸盔,位于F島的核電站,受9級特大地震影響琳省,放射性物質(zhì)發(fā)生泄漏迎吵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一针贬、第九天 我趴在偏房一處隱蔽的房頂上張望击费。 院中可真熱鬧,春花似錦桦他、人聲如沸蔫巩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽圆仔。三九已至,卻和暖如春蔫劣,著一層夾襖步出監(jiān)牢的瞬間坪郭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工脉幢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留截粗,地道東北人信姓。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像绸罗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子豆瘫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • C/C++輸入輸出流總結(jié) 前兩天寫C++實習(xí)作業(yè)珊蟀,突然發(fā)現(xiàn)I/O是那么的陌生,打了好長時間的文件都沒有打開外驱,今天終...
    LuckTime閱讀 1,731評論 0 6
  • PHP常用函數(shù)大全 usleep() 函數(shù)延遲代碼執(zhí)行若干微秒育灸。 unpack() 函數(shù)從二進制字符串對數(shù)據(jù)進行解...
    上街買菜丶迷倒老太閱讀 1,369評論 0 20
  • php usleep() 函數(shù)延遲代碼執(zhí)行若干微秒。 unpack() 函數(shù)從二進制字符串對數(shù)據(jù)進行解包昵宇。 uni...
    思夢PHP閱讀 1,984評論 1 24
  • 單例 單例是一種設(shè)計模式磅崭,確保一個類最多同時存在一個實例,并易于訪問瓦哎。 單例實現(xiàn) 1砸喻、私有構(gòu)造方法 2、內(nèi)部鍵靜態(tài)...
    BruceLeeJ閱讀 143評論 0 0
  • 又到了交作業(yè)的日子 實在不知道該寫什么 這說明什么蒋譬? 內(nèi)心空空割岛,沒有可以表達的東西 思想懶惰,不愿意深入思考犯助,并記...
    斜杠中年再學(xué)習(xí)閱讀 501評論 0 51