讀文本文件 :一般都使用 getc 、fgets 、fscanf 函數(shù)
東源ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!使用getc讀文件
#includeint main()
{char a[20] = "a.txt";
FILE *p = fopen(a,"r");
if(p)
{char c;
while(1)
{c = getc(p);
if(c == EOF)
break;
printf("%c",c);
}
printf("\n");
fclose(p);
}
else
{printf("fail\n");
}
return 0;
}
使用fgets讀文件
#includeint main()
{FILE *p = fopen("test.txt","r");
if(p == NULL)
return 0;
char temp[1024];
fgets(temp,sizeof(temp),p);
while(!feof(p))
{printf("%s",temp);
fgets(temp,sizeof(temp),p);
}
fclose(p);
return 0;
}
使用fscanf讀文件
#includeint main()
{FILE *p = fopen("a.txt", "r");
if(p == NULL)
{printf("the file is close!");
return 0;
}
char str1[200], str2[200], str3[200];
int year;
int status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year);
while(!feof(p))
{printf("%s %s %d %d status = %d\n", str1, str2, str3, year, status);
status = fscanf(p, "%s %s %s %d", str1, str2, str3, &year);
}
fclose(p);
return 0;
}
寫(xiě)文本文件 :一般都使用 putc 、 fputs、fprintf 函數(shù)
使用putc寫(xiě)文件
#includeint main()
{FILE *p = fopen("a.txt","w");
if(p)
{putc('h',p);
fclose(p);
}
return 0;
}
使用fputs寫(xiě)文件
#includeint main()
{FILE *p = fopen("abc.c","w");
if(p)
{fputs("#include\nint main()\n{\nprintf(\"hello world\\n\");\nreturn 0;\n}",p);
fclose(p);
}
return 0;
}
使用fprintf寫(xiě)文件
#include#includeint main()
{FILE *p = fopen("a.txt","w");
char buf[1024];
fgets(buf, sizeof(buf), stdin);
while(strcmp(buf,"exit\n") != 0)
{ fprintf(p, "%s", buf);
fgets(buf, sizeof(buf), stdin);
}
fclose(p);
return 0;
}
讀二進(jìn)制文件: 使用fread 函數(shù)
代碼:
#includevoid readFile()
{FILE *p = fopen("a.txt", "rb");
char buf[20] = {0 };
int index = 0;
while(1)
{int res = fread(buf, 1, 5, p);
printf("res = %d , ", res);
if(feof(p))
break;
printf("buf = %s\n",buf);
index++;
}
fclose(p);
printf("%d\n", index);
}
int main()
{readFile();
return 0;
}
寫(xiě)二進(jìn)制文件: 使用fwrite 函數(shù)
代碼
#includevoid writeFile()
{FILE *p = fopen("b.txt", "w");
char buf = 'a';
int i;
for(i = 0; i< 10 ; i++)
{fwrite(&buf, 1, 1, p);
buf++;
}
fclose(p);
}
int main()
{writeFile();
return 0;
}
眾所周知,我們的計(jì)算機(jī)操作系統(tǒng)都是由C語(yǔ)言寫(xiě)的,通過(guò)C語(yǔ)言協(xié)調(diào)物理內(nèi)存與虛擬內(nèi)存,操作系統(tǒng)想要向物理內(nèi)存中寫(xiě)數(shù)據(jù)的時(shí)候,會(huì)費(fèi)很大的力。
寫(xiě)數(shù)據(jù)到物理內(nèi)存
當(dāng)操作系統(tǒng)有一個(gè)字節(jié)的數(shù)據(jù)想要寫(xiě)入物理磁盤(pán)中,首先要經(jīng)歷一下幾個(gè)步驟:
從磁盤(pán)中讀數(shù)據(jù)
讀數(shù)據(jù)的操作與寫(xiě)數(shù)據(jù)的操作正好相反,也是要經(jīng)歷總線請(qǐng)求與總線釋放的過(guò)程。
總之,操作系統(tǒng)想要往磁盤(pán)中讀寫(xiě)數(shù)據(jù)要經(jīng)歷很繁瑣的過(guò)程。
(2)操作系統(tǒng)封裝讀寫(xiě)數(shù)據(jù)函數(shù)接口每次操作系統(tǒng)與磁盤(pán)進(jìn)行數(shù)據(jù)交互的時(shí)候,都會(huì)對(duì)CPU有一系列的操作指令,這些讀寫(xiě)指令的合集就是讀寫(xiě)函數(shù),通過(guò)C語(yǔ)言實(shí)現(xiàn)這些讀寫(xiě)函數(shù)再往外部拋出一系列的接口,就實(shí)現(xiàn)的讀寫(xiě)數(shù)據(jù)的函數(shù)封裝。
當(dāng)用戶想往磁盤(pán)中寫(xiě)入數(shù)據(jù)的時(shí)候只需要調(diào)用這些函數(shù)接口就行了。
然而這些函數(shù)都是針對(duì)最底層的數(shù)據(jù)存儲(chǔ)操作,不利于計(jì)算機(jī)的操作性能提高,所以,有人就在這層函數(shù)的基礎(chǔ)上再次進(jìn)行封裝,把性能更加好,更加優(yōu)化的讀寫(xiě)數(shù)據(jù)函數(shù)封裝到C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)中。
在標(biāo)準(zhǔn)庫(kù)中的讀寫(xiě)數(shù)據(jù)函數(shù),例如fwrite和fputs等等。它們不是每次寫(xiě)入一個(gè)字節(jié)數(shù)據(jù)就往物理磁盤(pán)中寫(xiě)入數(shù)據(jù),而是利用函數(shù)在內(nèi)存中開(kāi)辟出一個(gè)固定大小的字節(jié)緩沖池,通過(guò)這個(gè)緩沖池,來(lái)實(shí)現(xiàn)數(shù)據(jù)的讀與寫(xiě)。
(3)C語(yǔ)言中的數(shù)據(jù)緩沖池C語(yǔ)言的所有讀寫(xiě)函數(shù),都會(huì)使用到數(shù)據(jù)緩沖池,無(wú)論是讀數(shù)據(jù)操作,還是寫(xiě)數(shù)據(jù)操作,都會(huì)把數(shù)據(jù)臨時(shí)存儲(chǔ)到這里。
寫(xiě)數(shù)據(jù)
當(dāng)我們使用C語(yǔ)言往文件中寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù)的時(shí)候,會(huì)經(jīng)歷一下幾個(gè)步驟:
從上面的步驟中可以看出我們的函數(shù)在執(zhí)行到寫(xiě)入數(shù)據(jù)的操作的時(shí)候,數(shù)據(jù)并沒(méi)有真正的寫(xiě)入到磁盤(pán)中,而是等到寫(xiě)入文件的操作結(jié)束的時(shí)候,才把數(shù)據(jù)緩沖池中的數(shù)據(jù)寫(xiě)入磁盤(pán)中。
同樣的我們使用C語(yǔ)言讀一個(gè)字節(jié)數(shù)據(jù)的時(shí)候,同樣會(huì)經(jīng)歷一下步驟:
緩沖池工作原理
當(dāng)知道我們的所有讀寫(xiě)操作都要進(jìn)入緩沖池時(shí),我們同樣要知道緩沖池的工作原理。
緩沖池有一定固定的大小
緩沖池在進(jìn)行讀數(shù)據(jù)的操作時(shí),如果要讀取的數(shù)據(jù)字節(jié)小于緩沖池的大小,緩沖池會(huì)從磁盤(pán)中讀取滿整個(gè)緩沖池的數(shù)據(jù),所以當(dāng)每次讀取的字節(jié)數(shù)過(guò)小,讀取次數(shù)過(guò)多的時(shí)候,會(huì)減少訪問(wèn)實(shí)際磁盤(pán)的磁盤(pán),增加程序運(yùn)行的性能。
緩沖池的刷新,每刷新一次都會(huì)進(jìn)行與實(shí)際物理內(nèi)存的交互。
當(dāng)緩沖池滿了或者目標(biāo)操作文件關(guān)閉的時(shí)候,緩沖池會(huì)自動(dòng)刷新,寫(xiě)數(shù)據(jù)時(shí),緩沖池的數(shù)據(jù)會(huì)進(jìn)入物理磁盤(pán);讀數(shù)據(jù)時(shí),緩沖池的數(shù)據(jù)會(huì)數(shù)據(jù)固定字節(jié)的數(shù)據(jù)進(jìn)入輸出終端。
總而言之,緩沖池僅僅是用戶與物理磁盤(pán)之間數(shù)據(jù)交戶的一個(gè)緩沖而已,不用想的太深?yuàn)W。
三、使用函數(shù)刷新緩沖池 fflush函數(shù):函數(shù)作用:
刷新緩沖池
函數(shù)定義:
int fflush(FILE *P);
參數(shù) 返回值:
使用示例:
現(xiàn)有空文件a.txt
利用標(biāo)準(zhǔn)輸入數(shù)據(jù),在文件沒(méi)有關(guān)閉的時(shí)候,查看文件內(nèi)是否有寫(xiě)入的數(shù)據(jù)。
#include#includevoid write_file()
{FILE *p = fopen("a.txt", "w");
char temp[100] = {0 };
while(1)
{fgets(temp, sizeof(temp), stdin);
if(strcmp(temp, "exit\n") == 0)
break;
fprintf(p, "%s", temp);
}
fclose(p);
}
int main()
{write_file();
return 0;
}
運(yùn)行結(jié)果:
輸入中
[文件]$ gcc -o a fflush.c
[文件]$ a
hello
查看文件a.txt
可以看到文件為空,輸入的文件現(xiàn)在正存儲(chǔ)在緩沖池中。
輸入exit退出輸入,查看文件a
[文件]$ cat a.txt
hello
文件關(guān)閉,緩沖池中的數(shù)據(jù)寫(xiě)入磁盤(pán)。
現(xiàn)在我們創(chuàng)建一個(gè)函數(shù)使每輸入一次都寫(xiě)入一次磁盤(pán):
#include#includevoid write_file()
{FILE *p = fopen("a.txt", "w");
char temp[100] = {0 };
while(1)
{fgets(temp, sizeof(temp), stdin);
if(strcmp(temp, "exit\n") == 0)
break;
fprintf(p, "%s", temp);
fflush(p);
}
fclose(p);
}
int main()
{write_file();
return 0;
}
運(yùn)行結(jié)果:
輸入中,查看a.txt
[文件]$ gcc -o a fflush.c
[文件]$ a
hello
再開(kāi)啟另一個(gè)終端查看文件 a.txt 狀態(tài):
[文件]$ cat a.txt
hello
輸入結(jié)束,查看a.txt
[文件]$ a
hello
exit
[文件]$ cat a.txt
hello
[文件]$
可以看到使用fflush函數(shù)把緩沖池中的數(shù)據(jù)寫(xiě)入了磁盤(pán)。
四、總結(jié)當(dāng)我們?cè)谕疟P(pán)中錄入重要的非常重要的數(shù)據(jù)的時(shí)候,一定要使用fflush不斷的刷新緩沖池,因?yàn)閿?shù)據(jù)非常重要;但我們輸入不重要的數(shù)據(jù)是一定要盡量減少使用fflush函數(shù)的次數(shù),因?yàn)槟菢訒?huì)讓程序變得緩慢。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧