常規(guī)文件操作順序(大象冰箱)
- 第一,先打開文件 fopen
- 第二,讀寫文件 getc
- 第三,關(guān)閉文件
1.Fopen
FILE *fopen(const char *path, const char *mode);
Fopen打開文件成功,返回有效FILE的有效地址,失敗返回NULL
Path就是指定打開文件的路徑,可以是相對路徑,也可以是絕對路徑
#pragma waning(disable:4996)
FILE *p = fopen("D:\\temp\\a.txt","r");//‘\’轉(zhuǎn)意符
if(p==NULL) printf("失敗\n");
else printf("成功\n");
mode有以下幾個值:
r 以只讀方式打開文件,該文件必須存在,文件必須是可讀的。
r+ 以可讀寫方式打開文件,該文件必須存在。
rb+ 讀寫打開一個二進制文件,允許讀寫數(shù)據(jù),文件必須存在。
rw+ 讀寫打開一個文本文件,允許讀和寫。
w 打開只寫文件,若文件存在則文件長度清為0,即該文件內(nèi)容會消失。若文件不存在則建立該文件。
w+ 打開可讀寫文件,若文件存在則文件長度清為零,即該文件內(nèi)容會消失。若文件不存在則建立該文件。
a 以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數(shù)據(jù)會被加到文件尾,即文件原先的內(nèi)容會被保留。(EOF符保留)
a+ 以附加方式打開可讀寫的文件。若文件不存在,則會建立該文件,如果文件存在,寫入的數(shù)據(jù)會被加到文件尾后,即文件原先的內(nèi)容會被保留。 (原來的EOF符不保留)
1.1 二進制和文本模式的區(qū)別
1.在windows系統(tǒng)中,文本模式下,文件以"\r\n"代表換行。若以文本模式打開文件,并用fputs等函數(shù)寫入換行符"\n"時,函數(shù)會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n" 。
2.在類Unix/Linux系統(tǒng)中文本模式下,文件以"\n"代表換行。所以Linux系統(tǒng)中在文本模式和二進制模式下并無區(qū)別。
在windows讀寫文本文件的時候,是不寫b(rb或wb),但讀寫二進制文件的時候一定要寫b
Linux,b是忽略的。
2.getc和putc函數(shù)
int getc(FILE *stream);
getc的參數(shù)是fopen成功打開文件后返回的指針,getc的返回值是一個char
getc的功能是以字節(jié)位單位讀取文件內(nèi)容
文本文件的最后結(jié)束標示是-1,也就是一個宏EOF
#define EOF -1
int putc(int c, FILE *stream);第一個參數(shù)是要寫入的char,第二個參數(shù)是fopen返回的文件指針
int main()
{
FILE *fp = fopen("a.txt", "w");
const char *s = "hello world";
int i;
for (i = 0; i < strlen(s); i++)
{
putc(s[i], fp);
}
fclose(fp);
return 0;
}
#pragma waning(disable:4996)
FILE *p = fopen("D:\\temp\\a.txt","r");//‘\’轉(zhuǎn)意符
//p這個指針程序員一般是不用來計算的,主要的用處是給c語言庫函數(shù)作為參數(shù)使用
if(p==NULL) printf("失敗\n");
else
{
printf("成功\n");
/*
char c = getc(p);//fopen返回的指針,是不能自己計算的,一定是要給c語言文件操作的庫函數(shù)操作
//第二次調(diào)用getc的時候,getc會自動從第二個BYTE開始讀取文件的內(nèi)容,這個是不需要我們通過代碼干預的
printf("%s\n",c);//這里只輸出了第一個字符!
*/
char c= 0;
while(c != EOF)//只要不是文件結(jié)尾,那么就一直循環(huán)
{
c = getc(p);
printf("%c",c);
}
fclose(p);//fopen成功
}
return 0;
}
如果打開的文件,不關(guān)閉,一定消耗內(nèi)存,同時一個進程同時打開的文件數(shù)是有限的
即使不關(guān)閉文件,進程在執(zhí)行完成退出的時候,操作系統(tǒng)自動把進程打開的文件都關(guān)閉
但不要依賴操作系統(tǒng)關(guān)閉文件,還是需要在代碼中主動將文件關(guān)閉
FILE *fopen();//這個函數(shù)一定是操作了堆空間的
fclose(p);//可以把fopen在堆中申請的空間free掉
2.文件拷貝代碼
int main()
{
FILE *p1 = fopen("D:\\temp\\a.txt","r");//用讀的方式打開a.txt
FILE *p2 = fopen("D:\\temp\\b.txt","w");//用寫的方式打開b.txt
if(p1&&p2)
{
//讀取p1,將讀到的內(nèi)容寫入p2,就實現(xiàn)了文件的拷貝
while(1)
{
char c = getc(p1);//從p1中讀一個字節(jié)
if(c == EOF)break;
c++;//普通加密,下面寫讀取加密文件
putc(c,p2);//將p1中讀到的字節(jié)寫入p2
}
fclose(p1);
fclose(p2);
}
return 0
}
int main()//讀加密文件
{
FILE *p = fopen("D:\\temp\\b.txt","r");
if(p)
{
while(1)
{
char c = getc(p);
if(c==EOF)break;
c--;
printf("%c",c);
}
fclose(p);
}
return 0;
}
3. fprintf,fscanf,fgets,fputs函數(shù)
fgets和fputs可以看->字符串處理函數(shù)
這些函數(shù)都是通過FILE *來對文件進行讀寫。
Fgets的返回值是char *,代表函數(shù)讀到的字符串的首地址,如果fgets到了文件末尾,繼續(xù)調(diào)用,返回NULL
3.1EOF與feof函數(shù)文件結(jié)尾
程序怎么才能知道是否已經(jīng)到達文件結(jié)尾了呢?EOF代表文件結(jié)尾
如果已經(jīng)是文件尾,feof函數(shù)返回true。
int feof(FILE *stream);參數(shù)就是fopen返回的文件指針
#pragma warning(disable:4996)
int main()
{
FILE *p = fopen("D:\\temp\\a.txt","r");
if(p)
{
while(1)-------也可以這樣寫while(!feof(p)),其他細改!
{
char a[100] = {0};
fgets(a,sizeof(a),p);//從p中讀一行,包括行尾的回車
if(feof(p))break;//如果p已經(jīng)到了文件最好,feof返回true
printf("%s\n",a);
}
fclose(p);
}
return 0;
}
int main()//行寫文件
{
FILE *p = fopen("D:\\temp\\w.txt","r");
if(p)
{
//char a[100] = "hello world";
//fputs(a,p);
while(1)//實時輸入
{
char a[100] = {0};
scanf("%s",a);//scanf不會給你輸入回車
if(strcmp(a,"exit")==0)break;
//int len = strlen(a);
//a[len] = '\n';
fputs(a,p);
fputs('\n',p);//可以手動添加回車
}
flose(p);
}
return 0;
}