版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第10章文件10.1文件概述10.2文件的打開(kāi)與關(guān)閉10.3文件的讀/寫(xiě)操作10.4文件檢測(cè)函數(shù)10.5文件的定位10.6程序舉例習(xí)題10
本章學(xué)習(xí)要求:
1.了解文件的分類,了解文件函數(shù)使用時(shí)包含的頭文件。
2.掌握文件類型指針的定義,掌握文件打開(kāi)與關(guān)閉函數(shù)的使用,掌握文件讀/寫(xiě)操作函數(shù)的使用,掌握文件定位函數(shù)的使用,了解文件的檢索。
在前面所學(xué)的程序中,所有的程序都只能在運(yùn)行時(shí)輸入信息以及顯示執(zhí)行的結(jié)果,卻不能將一次輸入多次使用,并且又不能將執(zhí)行的結(jié)果保存起來(lái)以供查看,例如,在創(chuàng)建鏈表的實(shí)例中每次運(yùn)行時(shí)必須輸入一次鏈表中所有元素的信息,無(wú)法保存下來(lái),同時(shí)對(duì)經(jīng)過(guò)處理(如插入元素)的鏈表結(jié)果也無(wú)法保存下來(lái)。并且在運(yùn)行時(shí)如果需要輸入大量的數(shù)據(jù),在程序調(diào)試過(guò)程中也是比較麻煩的。因此,這就需要學(xué)習(xí)使用C語(yǔ)言編程對(duì)文件進(jìn)行訪問(wèn)。
10.1.1文件的概念與分類
文件(file)在程序設(shè)計(jì)中是一個(gè)比較重要的概念。一般來(lái)說(shuō),文件就是指存儲(chǔ)在外存儲(chǔ)器上數(shù)據(jù)的集合。每個(gè)文件都有一個(gè)屬于自己的名字,稱為文件名。文件名是讀取文件的依據(jù),也是標(biāo)識(shí)文件的方式,就像我們?nèi)说拿质敲總€(gè)人的標(biāo)識(shí)一樣。操作系統(tǒng)就是通過(guò)文件名對(duì)各種文件進(jìn)行存取和處理的,即“按名存取”。10.1文件概述
1.文件的分類
根據(jù)文件中數(shù)據(jù)的存儲(chǔ)形式,一般可以將文件分成文本文件和二進(jìn)制文件兩種。
文本文件又稱為ASCII碼文件。在這種文件中是以字符為單位進(jìn)行存放的,每個(gè)字節(jié)存放一個(gè)字符的ASCII碼值(取值范圍0~127)。例如,一個(gè)整數(shù)3267,它是由4個(gè)數(shù)字字符組成,在文本文件中需要用4個(gè)字節(jié)來(lái)存放4個(gè)數(shù)字字符,如圖10.1(a)所示。二進(jìn)制文件是以二進(jìn)制位(bit)為單位的,數(shù)據(jù)按其在內(nèi)存中的存儲(chǔ)形式直接存放到文件中,即在二進(jìn)制文件中,數(shù)據(jù)與該數(shù)據(jù)的二進(jìn)制形式是一致的,其中的一個(gè)字節(jié)并不代表一個(gè)字符。例如,同樣的一個(gè)整數(shù)3267,化成二進(jìn)制數(shù)為110011000011,因此,它在二進(jìn)制文件中只需要占2個(gè)字節(jié),如圖10.1(b)所示。
圖10.1整數(shù)3267在文件中的存儲(chǔ)形式
2.緩沖文件系統(tǒng)
C語(yǔ)言編譯系統(tǒng)對(duì)文件的處理有兩種方式,分別采用緩沖文件系統(tǒng)方式與非緩沖文件系統(tǒng)方式進(jìn)行。
緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地為正在被使用的文件在內(nèi)存中開(kāi)辟一個(gè)緩沖區(qū)。當(dāng)需要向外存中的文件輸出數(shù)據(jù)時(shí),必須先將數(shù)據(jù)送到為該文件開(kāi)辟的緩沖區(qū)中,當(dāng)緩沖區(qū)充滿后才一起送到外存中。當(dāng)需要對(duì)外存中的文件讀入數(shù)據(jù)時(shí),也先從外存一次將一批數(shù)據(jù)讀入緩沖區(qū)(將緩沖區(qū)充滿或?qū)⑺璧臄?shù)據(jù)全部讀入),然后再?gòu)木彌_區(qū)中將數(shù)據(jù)逐個(gè)讀入。在這種文件系統(tǒng)中,對(duì)文件的輸入/輸出是通過(guò)為該文件開(kāi)辟的緩沖區(qū)進(jìn)行的。緩沖文件系統(tǒng)又稱為高級(jí)文件系統(tǒng)。非緩沖文件系統(tǒng)是指系統(tǒng)不自動(dòng)為文件開(kāi)辟緩沖區(qū),而是由用戶程序自己為文件設(shè)定緩沖區(qū)。非緩沖文件系統(tǒng)又稱為低級(jí)文件系統(tǒng)。
ANSIC標(biāo)準(zhǔn)采用的是緩沖文件系統(tǒng),對(duì)文件的操作都通過(guò)標(biāo)準(zhǔn)庫(kù)函數(shù)來(lái)實(shí)現(xiàn)。
3.文件操作的步驟
程序?qū)ξ募M(jìn)行操作時(shí),一般要經(jīng)過(guò)以下三個(gè)步驟:
(1)打開(kāi)文件。用標(biāo)準(zhǔn)庫(kù)函數(shù)fopen()打開(kāi)文件,它通知編譯系統(tǒng)三個(gè)信息:需要打開(kāi)的文件名;使用文件的方式(讀還是寫(xiě)等);使用的文件指針。編譯系統(tǒng)將需要的文件調(diào)入內(nèi)存緩沖區(qū)。
(2)文件讀寫(xiě)。用文件輸入或輸出函數(shù)對(duì)文件進(jìn)行讀寫(xiě),這些輸入或輸出函數(shù)與前面介紹的標(biāo)準(zhǔn)輸入與輸出函數(shù)在功能上有相似之處,但在使用上又不相同。
(3)關(guān)閉文件。文件讀寫(xiě)完畢,用標(biāo)準(zhǔn)庫(kù)函數(shù)fclose()關(guān)閉文件。它的主要功能是將數(shù)據(jù)從內(nèi)存真正寫(xiě)入磁盤(pán)(否則數(shù)據(jù)可能還在內(nèi)存緩沖區(qū)中),切斷文件指針與文件名之間的聯(lián)系,釋放文件指針。如果文件使用完后不關(guān)閉可能會(huì)造成數(shù)據(jù)的丟失。因此,我們?cè)谑褂梦募r(shí),如果文件不再使用時(shí),及時(shí)關(guān)閉文件是一個(gè)好習(xí)慣。當(dāng)然,當(dāng)程序正常運(yùn)行結(jié)束時(shí),系統(tǒng)也會(huì)自動(dòng)關(guān)閉所有已經(jīng)打開(kāi)的文件。10.1.2文件類型指針
在進(jìn)行文件操作時(shí),要用文件指針。文件指針用來(lái)指向緩沖區(qū)中文件當(dāng)前操作的位置,當(dāng)文件指針與某個(gè)文件連接后,用戶就通過(guò)文件指針而不是文件名來(lái)存取文件。文件指針是由系統(tǒng)在頭文件stdio.h中定義的結(jié)構(gòu)類型,類型名為FILE,其成員分別用來(lái)存放文件名、文件狀態(tài)標(biāo)志及緩沖區(qū)大小等信息。有興趣的讀者可以到TurboC編譯系統(tǒng)的include文件夾中參閱stdio.h文件內(nèi)容,通常情況下不用了解其中的細(xì)節(jié),只要能用類型名FILE來(lái)定義文件指針就可以了。定義文件指針的一般形式如下:
FILE*指針變量名表列;
其中,指針變量名表列是指可以一次定義一個(gè)到多個(gè)文件指針,每個(gè)文件指針可以用于存放一個(gè)文件緩沖區(qū)的首地址。例如:
FILE*fp1,*fp2;
定義了名為fp1和fp2的兩個(gè)文件指針,可以由fopen()函數(shù)將它們分別指向一個(gè)文件。
注意:一個(gè)文件指針只能指向一個(gè)文件。如果想打開(kāi)幾個(gè)文件,就應(yīng)該有幾個(gè)文件指針。
10.2.1文件的打開(kāi)
打開(kāi)文件要用庫(kù)函數(shù)fopen(),其調(diào)用的一般格式如下:
FILE*fp;/*也可以用其他文件指針變量名,這里用fp作為文件指針變量名*/
…
fp=fopen("文件名","文件使用方式");
從上述格式可以看出,要想打開(kāi)一個(gè)文件,必須先為該文件定義一個(gè)文件類型指針,然后才能用fopen()函數(shù)打開(kāi)文件。10.2文件的打開(kāi)與關(guān)閉
fopen()函數(shù)在調(diào)用時(shí)有兩個(gè)參數(shù):“文件名”與“文件使用方式”,它們都是字符串。其中“文件名”是要打開(kāi)的文件的名字,當(dāng)然可以帶文件路徑,但在文件路徑中的“\”必須使用轉(zhuǎn)義字符,例如:fopen("c:\\tc20\\t.txt","w")就是正確打開(kāi)帶路徑文件的方式;“文件使用方式”規(guī)定了打開(kāi)文件的目的,如表10.1所示。
fopen()函數(shù)的主要功能是為需要打開(kāi)的文件分配一個(gè)緩沖區(qū),并返回該緩沖區(qū)的首地址。如果文件打開(kāi)不成功(可能找不到對(duì)應(yīng)的文件),則返回NULL(或0),NULL是一個(gè)空指針值,也是由stdio.h頭文件定義的。
表10.1文件使用方式為確保文件的正常操作,有必要在程序中檢測(cè)文件是否正常打開(kāi),即打開(kāi)文件的操作是否成功。常用下面的程序段來(lái)打開(kāi)文件:
if((fp=fopen("filename","w"))==NULL)
{printf("Cannotopenfile!\n");exit(1);}
這樣,當(dāng)文件不能正常打開(kāi)時(shí),屏幕提示“Cannotopenfile!”,程序運(yùn)行終止,返回操作系統(tǒng)。exit()函數(shù)的功能是終止程序運(yùn)行,關(guān)閉文件并返回操作系統(tǒng),它也是在stdio.h頭文件中定義的;如果文件打開(kāi)成功,程序就可以繼續(xù)執(zhí)行。10.2.2文件的關(guān)閉
對(duì)文件操作完成后,必須關(guān)閉文件,以保證本次文件操作有效。文件關(guān)閉使用fclose()標(biāo)準(zhǔn)庫(kù)函數(shù),其一般形式如下:
fclose(文件指針變量名);
例如,要關(guān)閉前面的文件指針變量fp指向的文件,可以使用fclose(fp);來(lái)關(guān)閉。若關(guān)閉成功則返回0,否則返回EOF(即-1)??梢杂胒error()函數(shù)來(lái)測(cè)試。
10.3.1文件讀函數(shù)
對(duì)文件進(jìn)行讀操作,是指從外存儲(chǔ)器的文件中向程序輸入數(shù)據(jù)。
在C語(yǔ)言中,讀文件的函數(shù)主要有:fgetc()、fread()、fscanf()。
10.3文件的讀/寫(xiě)操作
1.?fgetc()函數(shù)
fgetc()函數(shù)的功能是:從指定的文件讀入一個(gè)字符。其一般格式如下:
charc;
c=fgetc(fp);
其中:fp是已經(jīng)定義過(guò)的文件指針變量,該函數(shù)從fp指向的文件中的當(dāng)前位置讀取一個(gè)字符,并將該字符的ASCII碼值保存到字符變量c中。
當(dāng)讀到文件末尾或讀取出錯(cuò)時(shí),該函數(shù)返回一個(gè)文件結(jié)束標(biāo)志EOF(-1)。因?yàn)樽址腁SCII碼為非負(fù)值,所以可以用EOF(-1)作為結(jié)束標(biāo)志,即當(dāng)讀入的字符值等于EOF時(shí)表示文件已經(jīng)結(jié)束。
2.?fgets()函數(shù)
fgets()函數(shù)的功能是:從指定的文件中讀出一個(gè)字符串,其一般格式如下:
fgets(s,n,fp);
其中:s可以是字符型數(shù)組名或字符串指針,n是指定讀入的字符個(gè)數(shù),fp是文件指針變量。使用上面格式最多從文件中讀出n-1個(gè)字符,并將讀出的字符串存入指針s。當(dāng)函數(shù)讀取的字符達(dá)到指定的個(gè)數(shù)(n-1個(gè)),或者接收到換行符,再或者接收到文件結(jié)束標(biāo)志EOF時(shí),將在讀取的字符后面自動(dòng)添加一個(gè)字符串結(jié)束標(biāo)志'\0';若有換行符,則將換行符保留在'\0'字符之后;若有EOF,則不保留文件結(jié)束標(biāo)志EOF。
該函數(shù)如果執(zhí)行成功,返回讀取的字符串指針;如果失敗,則返回空指針,此時(shí),s中的內(nèi)容不確定。
3.?fread()函數(shù)
fread()函數(shù)的功能是:從指定的文件中讀入一組數(shù)據(jù)。其一般格式如下:
fread(buffer,size,count,fp);
其中:buffer表示存放讀入數(shù)據(jù)的內(nèi)存首地址,比如數(shù)組名;size表示每個(gè)數(shù)據(jù)項(xiàng)的字節(jié)數(shù);count表示數(shù)據(jù)項(xiàng)個(gè)數(shù);fp表示文件指針變量。
本函數(shù)是從fp指向的文件中,一次讀出長(zhǎng)度為size字節(jié)的count個(gè)數(shù)據(jù)項(xiàng),然后存放在buffer中。在讀出過(guò)程中,自動(dòng)把文件中的回車符、表示制表符和換行符的轉(zhuǎn)義序列轉(zhuǎn)換成換行符。該函數(shù)如果執(zhí)行成功,則返回實(shí)際讀出的數(shù)據(jù)項(xiàng)個(gè)數(shù);如果讀出數(shù)據(jù)項(xiàng)比調(diào)用中所需數(shù)據(jù)項(xiàng)少,則出錯(cuò)。關(guān)于出錯(cuò)的判斷見(jiàn)下一節(jié)的介紹。
4.?fscanf()函數(shù)
fscanf()函數(shù)的功能是:從指定的文件中格式化讀取數(shù)據(jù)。其一般格式如下:
fscanf(文件指針變量,格式控制串,地址表);
本函數(shù)與格式輸入函數(shù)scanf()很相似,其中,“格式控制串”和“地址表”的用法與scanf()函數(shù)相同。它們的區(qū)別就在于,scanf()函數(shù)是從鍵盤(pán)輸入數(shù)據(jù),而fscanf()函數(shù)是從文件讀入數(shù)據(jù),因此在fscanf()函數(shù)參數(shù)中多了一個(gè)文件指針,用于指出從哪個(gè)文件讀入數(shù)據(jù)。該函數(shù)如果執(zhí)行成功,則返回讀取項(xiàng)目的個(gè)數(shù);如果遇到文件末尾,則返回EOF;如果賦值失敗,則返回0。10.3.2文件寫(xiě)函數(shù)
對(duì)文件進(jìn)行寫(xiě)操作,就是將程序中處理好的數(shù)據(jù)寫(xiě)到指定的文件中。
在C語(yǔ)言中,讀文件的函數(shù)主要有fputc()、fputs()、fwrite()和fprintf()。
1.?fputc()函數(shù)
fputc()函數(shù)的功能是:將一個(gè)字符寫(xiě)到指定的文件中。其一般格式如下:
fputc(c,fp);
該函數(shù)將字符變量c中的字符碼值寫(xiě)入fp指向的文件當(dāng)前位置。如果寫(xiě)成功,則返回寫(xiě)入文件的字符,否則返回EOF。
例10.1
先從鍵盤(pán)輸入一串字符寫(xiě)入文件t1.txt中(當(dāng)輸入“#”時(shí)結(jié)束),并將文件t1.txt中的信息復(fù)制到文件t2.txt,最后在屏幕上顯示出文件t2.txt中的內(nèi)容。
問(wèn)題分析:本例可以分成三步進(jìn)行,第一步:從鍵盤(pán)輸入一串字符寫(xiě)入文件t1.txt,在進(jìn)行第二步前,必須將文件t1.txt的文件指針fp1復(fù)位到文件開(kāi)頭(可以使用rewind()函數(shù)或?qū)⑽募P(guān)閉,再打開(kāi));第二步:從文件t1.txt將內(nèi)容復(fù)制到文件t2.txt中,再將文件t2.txt的文件指針fp2復(fù)位到文件開(kāi)頭;第三步:將文件t2.txt的內(nèi)容顯示到屏幕上。程序如下:
#include<stdio.h>
main()
{charc;
FILE*fp1,*fp2;
if((fp1=fopen("t1.txt","w+"))==NULL)
{printf("Cannotopent1.txt!\n");exit(1);}
if((fp2=fopen("t2.txt","w+"))==NULL)
{printf("Cannotopent2.txt!\n");exit(1);}
while((c=getchar())!='#')/*從鍵盤(pán)輸入字符存入文件t1.txt中*/
fputc(c,fp1);
rewind(fp1);/*將文件t1.txt的文件指針移到文件開(kāi)頭*/
while((c=fgetc(fp1))!=EOF) /*將文件t1.txt的內(nèi)容復(fù)制到文 件t2.txt*/
fputc(c,fp2);
rewind(fp2);
while((c=fgetc(fp2))!=EOF) /*將文件t2.txt中的內(nèi)容輸出到 屏幕上*/
putchar(c);
fclose(fp1);fclose(fp2);
}
2.?fputs()函數(shù)
fputs()函數(shù)的功能是:將一個(gè)字符串寫(xiě)入指定的文件中。其一般格式如下:
fputs(s,fp);
其中,s可以是字符型數(shù)組名或字符串指針,fp是文件指針變量。
使用上面格式可以將字符串寫(xiě)入由fp指向的文件中,字符串結(jié)束標(biāo)志'\0'字符不寫(xiě)入。
該函數(shù)如果執(zhí)行成功,則返回寫(xiě)入的最后一個(gè)字符;如果失敗,則返回EOF。
例10.2
將字符串寫(xiě)入文件和讀出文件。
#include<stdio.h>
#include<string.h>
main()
{charstr[80],str1[80];
FILE*fp;
if((fp=fopen("t.txt","w+"))==NULL)
{printf("Cannotopent.txt!\n");exit(1);}
gets(str);
fputs(str,fp); /*將字符串寫(xiě)入文件中*/
rewind(fp); /*將文件指針復(fù)位到文件開(kāi)頭*/
fgets(str1,strlen(str)+1,fp); /*從文件中將字符串讀出*/
puts(str1); /*輸出到屏幕上*/
fclose(fp);
}
3.?fwrite()函數(shù)
fwrite()函數(shù)的功能是:將一組數(shù)據(jù)寫(xiě)到指定的文件中。其一般格式如下:
fwrite(buffer,size,count,fp);
其中:buffer 存放讀入數(shù)據(jù)的內(nèi)存首地址,比如數(shù)組名
size每個(gè)數(shù)據(jù)項(xiàng)的字節(jié)數(shù)
count數(shù)據(jù)項(xiàng)個(gè)數(shù)
fp文件指針變量本函數(shù)是向fp指向的文件中一次寫(xiě)入一個(gè)由buffer指向的數(shù)據(jù)塊,該數(shù)據(jù)塊共有count個(gè)數(shù)據(jù)項(xiàng),每個(gè)數(shù)據(jù)項(xiàng)有size個(gè)字節(jié)。
該函數(shù)如果執(zhí)行成功,則返回實(shí)際寫(xiě)入的數(shù)據(jù)項(xiàng)個(gè)數(shù);如果寫(xiě)入的數(shù)據(jù)項(xiàng)比調(diào)用中所需數(shù)據(jù)項(xiàng)少,則出錯(cuò)。關(guān)于出錯(cuò)的判斷見(jiàn)下一節(jié)的介紹。
例10.3
記錄型信息的訪問(wèn)。
在學(xué)習(xí)結(jié)構(gòu)體的時(shí)候我們就知道,真實(shí)的信息數(shù)據(jù)通常都是以記錄形式存在,而這種記錄可以通過(guò)結(jié)構(gòu)體來(lái)實(shí)現(xiàn),本例就是實(shí)現(xiàn)文件中記錄型信息的訪問(wèn)。
程序如下:
#include<stdio.h>
voidput_in(); /*聲明函數(shù)*/
voidget_out(); /*聲明函數(shù)*/
structstudent /*定義結(jié)構(gòu)體類型*/
{charname[10];
intscore;
}
main()
{
printf("Recorddataaccess!\n\n");
put_in(); /*調(diào)用文件寫(xiě)入函數(shù)*/
get_out(); /*調(diào)用文件讀出函數(shù)*/
}
/*寫(xiě)入文件函數(shù)*/
voidput_in()
{FILE*fp;
structstudentstud[]={{"張三",67},{"李四",78},{"王五",89},{"田三",92},{"趙七",54},
{"劉八",48}};
if((fp=fopen("stud.dat","wb"))==NULL)
{printf("Cannotcreatstud.dat!\n");exit(1);}
fwrite(stud,sizeof(structstudent),6,fp); /*將結(jié)構(gòu)體數(shù)組寫(xiě)入 文件中*/
fclose(fp);
printf("OK!\n");
}
/*讀出文件數(shù)據(jù)函數(shù)*/
voidget_out()
{FILE*fp;
structstudentstud[6];
inti;
if((fp=fopen("stud.dat","rb"))==NULL)
{printf("Cannotopenstud.dat!\n");exit(1);}
fread(stud,sizeof(structstudent),6,fp); /*從文件中讀出數(shù)據(jù) 放入結(jié)構(gòu)體數(shù)組*/
printf("姓名\t成績(jī)\n");
printf("----\t----\n");
for(i=0;i<6;i++)
printf("%s\t%d\n",stud[i].name,stud[i].score);
printf("\n");
fclose(fp);
}程序運(yùn)行結(jié)果如下:
Recorddataaccess!
OK!
姓名成績(jī)
--------
張三67
李四78
王五89
田三92
趙七54
劉八48
4.?fprintf()函數(shù)
fprintf()函數(shù)的功能是:向指定的文件中格式化寫(xiě)入數(shù)據(jù)。其一般格式如下:
fprintf(文件指針變量,格式控制串,輸出表);
其中:輸出表是由表達(dá)式組成的表列。
本函數(shù)與格式輸出函數(shù)printf()很相似,其中“格式控制串”和“輸出表”的用法與printf()函數(shù)相同。它們的區(qū)別就在于,printf()函數(shù)是將數(shù)據(jù)輸出到顯示屏幕上,而fprintf()函數(shù)是將數(shù)據(jù)輸出到文件中,因此在fprintf()函數(shù)參數(shù)中多了一個(gè)文件指針,用于指出將數(shù)據(jù)輸出到哪個(gè)文件中。
fprintf()函數(shù)與fscanf()函數(shù)是對(duì)應(yīng)的,最好結(jié)合使用。即使用fprintf()函數(shù)向文件中格式化寫(xiě)入數(shù)據(jù),而用fscanf()函數(shù)將數(shù)據(jù)從文件中格式化讀出。因此,在使用fprintf()函數(shù)時(shí),其格式應(yīng)與用fscanf()函數(shù)將數(shù)據(jù)從該文件讀出時(shí)的格式一致,否則會(huì)導(dǎo)致讀/寫(xiě)錯(cuò)誤。
該函數(shù)如果執(zhí)行成功,則返回實(shí)際寫(xiě)入文件的字符個(gè)數(shù);若出現(xiàn)錯(cuò)誤,則返回負(fù)數(shù)。
例10.4
從鍵盤(pán)輸入一個(gè)整數(shù)、一個(gè)實(shí)數(shù)、一個(gè)字符,將其寫(xiě)入文件ttt.txt,再將其從文件中讀出,輸出到屏幕上。
問(wèn)題分析:本例可以先分別定義一個(gè)整型、實(shí)型、字符型變量,再?gòu)逆I盤(pán)各輸入一個(gè)值,使用fprintf()函數(shù)將三個(gè)值按相應(yīng)格式寫(xiě)入到文件ttt.txt中,再使用fscanf()函數(shù)從文件中讀出,并使用格式輸出printf()函數(shù)輸出到屏幕上。程序如下:
#include<stdio.h>
main()
{inta,a1;floatb,b1;charc,c1;
FILE*fp;
if((fp=fopen("ttt.txt","w+"))==NULL)
{printf("Cannotopenfile!\n");exit(1);}
printf("Pleasea,b,c:");
scanf("%d,%f,%c",&a,&b,&c);
fprintf(fp,"%d,%f,%c",a,b,c);
/*rewind(fp);*//*將文件指針置于文件開(kāi)頭位置*/
fclose(fp);
fp=fopen("ttt.txt","r");
fscanf(fp,"%d,%f,%c",&a1,&b1,&c1);
printf("%d,%f,%c\n",a,b,c);
printf("%d,%f,%c\n",a1,b1,c1);
}注意:程序中將三個(gè)數(shù)寫(xiě)入文件后,將文件關(guān)閉,再以只讀的方式打開(kāi),并且重新格式化讀出數(shù)據(jù)。如果不這樣做(寫(xiě)入文件后馬上讀出)就會(huì)造成讀出的數(shù)據(jù)不對(duì),為什么呢?因?yàn)槲覀兿蛭募袑?xiě)完數(shù)據(jù)后,文件指針此時(shí)停留在文件尾,如果馬上讀取就會(huì)從文件指針當(dāng)前位置向后讀,顯然讀取的數(shù)據(jù)不對(duì)。要想解決這樣的問(wèn)題,可以使用兩種方法:①使用rewind(fp)函數(shù)將文件指針移到文件開(kāi)頭位置;②先將文件關(guān)閉,再以只讀的方式打開(kāi)。
文件檢測(cè)函數(shù)用于檢測(cè)文件指針是否到文件末尾,或文件讀/寫(xiě)操作中是否出現(xiàn)錯(cuò)誤等情況,以便能正確地進(jìn)行文件的存取。10.4文件檢測(cè)函數(shù)
1.?feof()函數(shù)
feof()函數(shù)用于二進(jìn)制文件結(jié)束檢測(cè)。對(duì)于文本文件,通??捎肊OF作為結(jié)束標(biāo)志,EOF的值為-1,因?yàn)槿魏蜛SCII碼都不可能取負(fù)值,所以它在文本文件中不會(huì)產(chǎn)生沖突。而對(duì)于二進(jìn)制文件,-1可能是字節(jié)數(shù)據(jù)的值,所以EOF不能作為二進(jìn)制文件的結(jié)束標(biāo)志。因此,二進(jìn)制文件結(jié)束的判斷只能使用feof()函數(shù)來(lái)完成,它的一般格式如下:
feof(fp);
其中:fp是已定義過(guò)的文件指針。該函數(shù)用于檢測(cè)文件是否結(jié)束,如果結(jié)束則返回非0值;否則返回0值。
2.?ferror()函數(shù)
ferror()函數(shù)用于檢測(cè)文件讀/寫(xiě)時(shí)是否發(fā)生錯(cuò)誤,其一般格式如下:
ferror(fp);
其中:fp是已定義過(guò)的文件指針。如果在文件讀/寫(xiě)過(guò)程中未發(fā)生錯(cuò)誤,則返回0值;否則,返回非0值。
3.?clearerr()函數(shù)
clearerr函數(shù)用于將文件的出錯(cuò)標(biāo)志和文件結(jié)束標(biāo)志置0。當(dāng)調(diào)用的文件輸入或輸出函數(shù)出錯(cuò)時(shí),ferror()函數(shù)給出非0的標(biāo)志,并一直保持此非0值,直到使用clearerr()函數(shù)或rewind()函數(shù)時(shí)才重新置0。其一般格式如下:
clearerr(fp);
其中:fp是已定義過(guò)的文件指針。使用clearerr()函數(shù)可以及時(shí)清除出錯(cuò)標(biāo)志。
為了正確地對(duì)文件進(jìn)行讀/寫(xiě)操作,在一個(gè)文件被打開(kāi)后,系統(tǒng)就為該文件設(shè)置一個(gè)讀/寫(xiě)指針,用于指示當(dāng)前讀/寫(xiě)的位置。當(dāng)進(jìn)行一次讀/寫(xiě)操作后,文件的讀/寫(xiě)指針位置自動(dòng)向后移動(dòng)。每次打開(kāi)文件總是從文件開(kāi)始位置進(jìn)行讀/寫(xiě)操作的,但有時(shí)文件經(jīng)過(guò)讀/寫(xiě)后,還需要回到文件頭;或有時(shí)需要直接修改文件中的某個(gè)部分內(nèi)容。對(duì)于這樣的情況,最好使用文件的定位函數(shù)。10.5文?件?的?定?位文件的定位函數(shù)主要有以下幾種。
1.?rewind()函數(shù)
有時(shí)文件經(jīng)過(guò)讀/寫(xiě)后,還需要回到文件頭以便訪問(wèn),而此時(shí)卻因?yàn)榍懊娴奈募僮魇刮募羔樢苿?dòng)到文件的其他位置,這時(shí)就需要重置文件指針使其回到文件頭。
rewind()函數(shù)的功能是:將文件指針重置于文件開(kāi)頭位置。其一般格式如下:
rewind(fp);
其中:fp是已定義過(guò)的文件指針。
2.?fseek()函數(shù)
fseek()函數(shù)的主要功能是:將文件的讀/寫(xiě)指針移動(dòng)到指定的位置。其一般格式如下:
fseek(fp,偏移量,起始位置);
其中:fp是已定義過(guò)的文件指針;起始位置是指移動(dòng)文件讀/寫(xiě)指針的參考位置,它有以下三個(gè)值:
SEEK_SET或0
表示文件開(kāi)頭
SEEK_CUR或1表示當(dāng)前讀/寫(xiě)的位置
SEEK_END或2表示文件末尾偏移量是相對(duì)“起始位置”的偏移字節(jié)數(shù),它要求是long型數(shù)據(jù)(可正可負(fù))。例如:
fseek(fp,100L,1);/*將文件指針從當(dāng)前讀/寫(xiě)位置向文件尾方向 移動(dòng)100個(gè)字節(jié)*/
fseek(fp,-10L,2);/*將文件指針從文件尾向文件頭方向移動(dòng)10 個(gè)字節(jié)*/
fseek(fp,100L,0);/*將文件指針從文件頭向文件尾方向移動(dòng)100 個(gè)字節(jié)*/
fseek()函數(shù)的意義在于:可以把文件指針移到文件的任何位置,實(shí)現(xiàn)對(duì)文件的隨機(jī)讀/寫(xiě)操作。
3.?ftell()函數(shù)
在程序執(zhí)行中,如果想要獲取文件指針的當(dāng)前位置,可以使用ftell()函數(shù)來(lái)完成。
ftell()函數(shù)的功能是:返回文件的當(dāng)前讀/寫(xiě)位置。其一般格式如下:
ftell(fp);
其中:fp是已定義過(guò)的文件指針。該函數(shù)如果執(zhí)行成功,則返回相對(duì)于文件頭的位移量(字節(jié)數(shù)),否則返回-1L。
例10.5
設(shè)有結(jié)構(gòu)體數(shù)組定義如下:
structstudent
{charname[10];
charsection[20];
intage,score;
}st[]={{"王小二","商學(xué)院",23,78},{"阮小二","理學(xué)院",22,80},{"阮小七",
"信息院",
21,65},{"孫二","人文學(xué)院",23,58},{"張三","農(nóng)學(xué)院",22,92}};10.6程序舉例編寫(xiě)如下程序:首先建立名為my_stud.dat的二進(jìn)制文件,用于保存給結(jié)構(gòu)體數(shù)組所賦的值;然后對(duì)上述學(xué)生數(shù)據(jù)按成績(jī)排序(降序),并將排完序的數(shù)據(jù)添加到原文件,并顯示到屏幕上。程序如下:
#include<stdio.h>
structstudent
{charname[10];
charsection[20];
intage,score;
}st[10]={{"王小二","商學(xué)院",23,78},{"阮小二","理學(xué)院",22,80},{"阮小七","信息院",
21,65},{"孫二","人文學(xué)院",23,58},{"張三","農(nóng)學(xué)院",22,92}},work;
voidsort()
{inti,j;
FILE*fp;
if((fp=fopen("my_stud.dat","rb"))==NULL)
{printf("Filecannotopen!\n");exit(1);}
for(i=0;i<5;i++) /*將數(shù)據(jù)從文件中讀出*/
fread(&st[i],sizeof(structstudent),1,fp);
for(i=0;i<5;i++)
for(j=i+1;j<5;j++)
if(st[i].score<st[j].score)
{work=st[i];
st[i]=st[j];
st[j]=work;
}
fclose(fp);
fp=fopen("my_stud.dat","ab");
fseek(fp,0,SEEK_END);
for(i=0;i<5;i++)
fwrite(&st[i],sizeof(structstudent),1,fp);
fclose(fp);
}
main()
{intk;
FILE*fp;
if((fp=fopen("my_stud.dat","wb"))==NULL)
{printf("Filecannotopen!\n");exit(1);}
for(k=0;k<5;k++) /*將數(shù)據(jù)寫(xiě)入文件*/
fwrite(&st[k],sizeof(structstudent),1,fp);
fclose(fp);
sort();
fp=fopen("my_stud.dat","rb");
clrscr();
printf("-----------排序前數(shù)據(jù)------------\n");
for(k=0;k<10;k++) /*將數(shù)據(jù)從文件中讀出*/
{fread(&st[k],sizeof(structstudent),1,fp);
printf("%s,%s,%d,%d\n",st[k].name,st[k].section,st[k].age,st[k].score);
if(k==4)
printf("-----------排序后數(shù)據(jù)-------------\n");
}
}程序運(yùn)行結(jié)果如下:
-----------排序前數(shù)據(jù)-------------
王小二,商學(xué)院,23,78
阮小二,理學(xué)院,22,80
阮小七,信息院,21,65
孫二,人文學(xué)院,23,58
張三,農(nóng)學(xué)院,22,92
-----------排序后數(shù)據(jù)-------------
張三,農(nóng)學(xué)院,22,92
阮小二,理學(xué)院,22,80
王小二,商學(xué)院,23,78
阮小七,信息院,21,65
孫二,人文學(xué)院,23,58
例10.6
建立my_stud.dat文件,將初始化的結(jié)構(gòu)化數(shù)組中的數(shù)據(jù)放入該文件中,并查詢出成績(jī)不及格的學(xué)生和成績(jī)優(yōu)良(>=80分)的學(xué)生。
程序如下:
/*成績(jī)查詢程序*/
#include<stdio.h>
structstudent
{charname[10];
charsection[20];
intage,score;
}st[]={{"王小二","商學(xué)院",23,78},{"阮小二","理學(xué)院",22,80},{"阮小七","信息院",21,65},
{"孫二","人文學(xué)院",23,58},{"張三","農(nóng)學(xué)院",22,92}};
main()
{FILE*fp;intk;
printf("成績(jī)查詢\n\n");
if((fp=fopen("my_stud.dat","wb"))==NULL)
{printf("Filecannotopen!\n");exit(1);}
for(k=0;k<5;k++) /*將數(shù)據(jù)寫(xiě)入文件中*/
fwrite(&st[k],sizeof(structstudent),1,fp);
fclose(fp);
if((fp=fopen("my_stud.dat","rb"))==NULL)
{printf("Filecannotopen!\n");exit(1);}
for(k=0;k<5;k++) /*將數(shù)據(jù)從文件中讀出*/
fread(&st[k],sizeof(structstudent),1,fp);
k=0;printf("不及格者姓名\t成績(jī)\n");
while(!feof(fp))
{fseek(fp,(long)sizeof(structstudent)*k,SEEK_SET);
fread(&st,sizeof(structstudent),1,fp);
if(st[k].score<60&&!feof(fp))
printf("%s\t\t%d\n",st[k].name,st[k].score);
k++;
}
rewind(fp);
k=0;printf("優(yōu)良者姓名\t成績(jī)\n");
while(!feof(fp))
{fseek(fp,(long)sizeof(structstudent)*k,SEEK_SET);
fread(&st,sizeof(structstudent),1,fp);
if(st[k].score>=80&&!feof(fp))
printf("%s\t\t%d\n",st[k].name,st[k].score);
k++;
}
fclose(fp);
}程序運(yùn)行結(jié)果如下:
成績(jī)查詢
不及格者姓名成績(jī)
孫二 58
優(yōu)良者姓名成績(jī)
阮小二 80
張三 92
例10.7
文本文件查看程序。
請(qǐng)完成類似DOS下type命令的功能,用于查看指定文本文件的內(nèi)容。查看的格式如:L10-07<文本文件名>。
/*L10-07.c*/
/*文本文件查看程序L10-07.c*/
#include<stdio.h>
main(intargc,char*argv[])
/*變量argc用來(lái)檢測(cè)輸入的參數(shù)項(xiàng) 目個(gè)數(shù),argv[]為一個(gè)字符指針數(shù)組,用于存放參數(shù)*/
{FILE*fp;
charletter[256];/*從文件中得到的數(shù)據(jù)將要存入的數(shù)組*/
intc,i;
if(argc<2)
{printf("命令的格式應(yīng)是:L10-07<文件名>\n");exit(1);}
if((fp=fopen(argv[1],"r"))==NULL)
{printf("不能打開(kāi)%s文件!\n",argv[1]);exit(1);}
do
{i=0;
while((c=fgetc(fp))!=EOF) /*從文件中讀出字符,并放到 字符數(shù)組letter中*/
{letter[i]=c;i++;
if(c=='\n')break;
}
letter[i]='\0';
printf("%s",letter); /*輸入字符數(shù)組*/
}while(c!=EOF);
fclose(fp);
}
說(shuō)明:先將程序編譯成可執(zhí)行文件L10-07.exe,再在DOS提示符下輸入以下命令行:
L10-07L10-07.c
這樣可以得到本例的源程序文件。
一、選擇題
1.
C語(yǔ)言文件的組成成分是()。
A.記錄B.數(shù)據(jù)行C.數(shù)據(jù)塊D.字符(字節(jié))系列
2.
C語(yǔ)言中,數(shù)據(jù)文件的存取方式為()。
A.只能順序存取
B.只能隨機(jī)存取(也叫直接存取)
C.可以順序存取和隨機(jī)存取
D.只能從文件的開(kāi)頭進(jìn)行存取習(xí)題10
3.以C語(yǔ)言中,用“a”方式打開(kāi)一個(gè)已含有10個(gè)字符的文本文件,并寫(xiě)入了8個(gè)新字符,則該文件中存放的字符是()。
A.新寫(xiě)入的8個(gè)字符
B.新寫(xiě)入的8個(gè)字符覆蓋原有字符中的前8個(gè)字符,保留原有的后2個(gè)字符
C.原有的10個(gè)字符在前,新寫(xiě)入的8個(gè)字符在后
D.新寫(xiě)入的8個(gè)字符在前,原有的10個(gè)字符在后
4.當(dāng)已存在一個(gè)t.txt文件時(shí),執(zhí)行函數(shù)fopen("t.txt","r+")的功能是()。
A.打開(kāi)t.txt文件,清除原有內(nèi)容
B.打開(kāi)t.txt文件,只能寫(xiě)入新的內(nèi)容
C.打開(kāi)t.txt文件,只能讀取原有的內(nèi)容
D.打開(kāi)t.txt文件,可以讀取和寫(xiě)入新的內(nèi)容
5.若用fopen()函數(shù)打開(kāi)一個(gè)新的二進(jìn)制文件,該文件可以讀也可以寫(xiě),則文件的使用方式是()。
A.
"ab+"B.
"wb+"C.
"rb+"D.
"ab"
6.若用fopen()函數(shù)打開(kāi)一個(gè)已存在的文件文件,保留該文件原有數(shù)據(jù)且可以讀也可以寫(xiě),則文件打開(kāi)方式是()。
A.
"r+"B.
"w+"C.
"a+"D.
"a"
7.
fseek函數(shù)可以實(shí)現(xiàn)的操作是()。
A.改變文件位置指針的當(dāng)前位置B.文件的順序讀/寫(xiě)
C.文件的隨機(jī)讀/寫(xiě)
D.以上都不對(duì)
8.以下不能將文件指針移到文件開(kāi)頭的函數(shù)是()。
A.
rewind(fp);
B.
fseek(fp,0,SEEK_SET);
C.
fseek(fp,-(long)ftell(fp),SEEK_CUR);
D.
fseek(fp,0,SEEK_END);
9.
fread(buf,64,2,fp)的功能是()。
A.從fp指向的文件中讀出整數(shù)64,并存放在buf中
B.從fp指向的文件中讀出整數(shù)64和2,并存放在buf中
C.從fp指向的文件中讀出64個(gè)字節(jié)的字符,并存放在buf中
D.從fp指向的文件中讀出2個(gè)64個(gè)字節(jié)的字符,并存放在buf中
10.檢測(cè)文件指針fp在文件頭的條件是()。
A.
fp==0 B.
ftell(fp)==0
C.
fseek(fp,0,SEEK_SET) D.
feof(fp)
11.
fgets(s,n,fp)函數(shù)的功能是從文件讀出字符串并存入內(nèi)存首地址s,以下敘述中正確的是()。
A.
n代表最少能讀出n個(gè)字符串
B.
n代表最多能讀出n個(gè)字符
C.
n代表最少能讀出n-1個(gè)字符串
D.
n代表最多能讀出n-1個(gè)字符
12.若fp是指向某文件的指針,且已讀到該文件的末尾,則函數(shù)feof(fp)的返回值是()。
A.
EOF B.-1 C.非0值 D.
NULL
13.執(zhí)行fseek(fp,-20L,1);后的結(jié)果是()。
A.將文件指針從當(dāng)前位置向文件末尾方向移動(dòng)20字節(jié)
B.將文件指針從文件頭向文件末尾方向移動(dòng)20字節(jié)
C.將文件指針從當(dāng)前位置向文件頭方向移動(dòng)20字節(jié)
D.將文件指針從文件末尾向文件頭方向移動(dòng)20字節(jié)
14.下列敘述中正確的是()。
A.
EOF只能作為二進(jìn)制文件的結(jié)束標(biāo)志,feof()只能用來(lái)判斷文本文件是否結(jié)束
B.
EOF只能作為文本文件的結(jié)束標(biāo)志,feof()只能用來(lái)判斷二進(jìn)制文件是否結(jié)束
C.
EOF可作為文本文件和二進(jìn)制文件的結(jié)束標(biāo)志,feof()只能用來(lái)判斷文本文件是否結(jié)束
D.
EOF只能作為文件文件的結(jié)束標(biāo)志,feof()則可以用來(lái)判斷文本文件和二進(jìn)制文件是否結(jié)束
15.若fp為文件指針,且文件已經(jīng)正確打開(kāi),則以下語(yǔ)句的輸出結(jié)果為()。
fseek(fp,0,SEEK_END);
n=ftell(fp);
printf("n=%d\n",n);
A.
fp所指文件的長(zhǎng)度,以字節(jié)為單位
B.
fp所指文件的當(dāng)前位置,以比特為單位
C.
fp所指文件的長(zhǎng)度,以比特為單位
D.
fp所指文件的當(dāng)前位置,以字節(jié)為單位
16.已知A盤(pán)根目錄下的一個(gè)文本數(shù)據(jù)文件data.dat中存儲(chǔ)了100個(gè)int型數(shù)據(jù),若需要修改該文件中已經(jīng)存在的若干個(gè)數(shù)據(jù)的值,只能調(diào)用一次fopen函數(shù),已有聲明語(yǔ)句“FILE*fp;”,則fopen函數(shù)的正確調(diào)用形式是()。
A.
fp=fopen("a:\\data.dat","r+");
B.
fp=fopen("a:\\data.dat","w+");
C.
fp=fopen("a:\\data.dat","a+");
D.
fp=fopen("a:\\data.dat","w");
17.已知有語(yǔ)句“FILE*fp;intx=123;fp=fopen("out.dat
","w");”,如果需要將變量x的值以文本形式保存到一個(gè)磁盤(pán)文件out.dat中,則以下函數(shù)調(diào)用形式中,正確的是()。
A.
fprintf("%d",x);
B.
fprintf(fp,"%d",x);
C.
fprintf("%d",x,fp);
D.
fprintf("out.dat","%d",x);
18.完成將文件指針fp重新指向文件開(kāi)頭的函數(shù)是()。
A.
feof(fp) B.
rewind(fp)
C.
fseek(fp) D.
ftell(fp)
19.要打開(kāi)一個(gè)已存在的非空文件“file”用于修改,正確的語(yǔ)句是()。
A.
fp=fopen("file","r");
B.
fp=fopen("file","a+");
C.
fp=fopen("file","w");
D.
fp=fopen("file","r+");
20.
fgets(str,n,fp)函數(shù)從文件中讀出一個(gè)字符串,以下正確的敘述是()。
A.字符串讀出后不會(huì)自動(dòng)加入'\0'
B.
fp是file類型的指針
C.
fgets函數(shù)將讀出文件中最多n-1個(gè)字符
D.
fgets函數(shù)將讀出文件中最多n個(gè)字符
二、填空題
1.已知聲明語(yǔ)句:“FILE*fp1,*fp2;longa[2]={12345678,12345678};”,當(dāng)執(zhí)行了以下語(yǔ)句后,文件f1.dat和f2.dat長(zhǎng)度分別為_(kāi)_________字節(jié)和_________字節(jié)。
fp1=fopen("f1.dat","w");fprintf(fp1,"%ld%ld",a[0],a[1]);fclose(fp1);
fp1=fopen("f2.dat","wb");fwrite(a,sizeof(long),2,fp2);fclose(fp2);
2.當(dāng)程序讀/寫(xiě)數(shù)據(jù)文件時(shí),需要有聲明語(yǔ)句“FILE*fp;”,在該聲明語(yǔ)句之前必須包含頭文件_______
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《離婚法律程序執(zhí)行細(xì)則協(xié)議》版
- 二零二五版保險(xiǎn)及期貨居間業(yè)務(wù)委托管理合同3篇
- 二零二五年度智慧社區(qū)商業(yè)配套租賃協(xié)議3篇
- 二零二五年度集成墻板原材料期貨交易與風(fēng)險(xiǎn)管理合同2篇
- 二零二五年度高端人才引進(jìn)與培養(yǎng)合同5篇
- 臨時(shí)建筑建設(shè)合同樣本2024年版版B版
- 2025年度智能廚房設(shè)備研發(fā)、安裝與培訓(xùn)服務(wù)合同3篇
- 二零二五版公共工程合同擔(dān)保制度及操作細(xì)則3篇
- 二零二五年電子設(shè)備采購(gòu)與技術(shù)服務(wù)合同2篇
- 2024年簡(jiǎn)化版資金借用協(xié)議范本版B版
- DB-T29-74-2018天津市城市道路工程施工及驗(yàn)收標(biāo)準(zhǔn)
- 小學(xué)一年級(jí)20以內(nèi)加減法混合運(yùn)算3000題(已排版)
- 智慧工廠數(shù)字孿生解決方案
- 病機(jī)-基本病機(jī) 邪正盛衰講解
- 品管圈知識(shí) 課件
- 非誠(chéng)不找小品臺(tái)詞
- 2024年3月江蘇省考公務(wù)員面試題(B類)及參考答案
- 患者信息保密法律法規(guī)解讀
- 老年人護(hù)理風(fēng)險(xiǎn)防控PPT
- 充電樁采購(gòu)安裝投標(biāo)方案(技術(shù)方案)
- 醫(yī)院科室考勤表
評(píng)論
0/150
提交評(píng)論