-
C第十二天
今天講的文件,內(nèi)容有點(diǎn)多,但是都屬于文件類的,到了后面把文件和鏈表結(jié)合的時(shí)候還是有點(diǎn)懵,自己寫不出來年枕。老師也說后期做項(xiàng)目主要由鏈表+結(jié)構(gòu)體+文件構(gòu)成,問題是現(xiàn)在這三樣我一個(gè)都沒掌握。老師給我們留了作業(yè),倒是把這幾天講的內(nèi)容都用上了。
文件:數(shù)據(jù)在硬盤上面的集合掷邦。是操作系統(tǒng)處理數(shù)據(jù)的單位。
文件格式分類:1.二進(jìn)制文件 ⊥指场2.文本文件
二進(jìn)制文件:存儲(chǔ)的時(shí)候以二進(jìn)制的形式把數(shù)據(jù)的補(bǔ)碼進(jìn)行存儲(chǔ)抚岗。
=>
1111... 1111... 111... 111...
x * & %
49 50 51 52 53
11111 111.. 111.. 111.. 11...
1 2 3 4 5 ```
直接打開文件是以文本的方式顯示,即一個(gè)字節(jié)一個(gè)字節(jié)的顯示哪怔。
文本文件:存儲(chǔ)的時(shí)候把每一個(gè)數(shù)據(jù)都看做是一個(gè)字符宣蔚,存儲(chǔ)他們的ASCii碼。這樣存儲(chǔ)的時(shí)候一個(gè)字符占一個(gè)字節(jié)认境。直接打開文件胚委,以文本的方式顯示,即能看到原文叉信。
文件分類:
從用戶的角度:
特殊文件:標(biāo)準(zhǔn)輸入輸出文件或者設(shè)備文件亩冬。
標(biāo)準(zhǔn)輸入:鍵盤 stdin
標(biāo)準(zhǔn)輸出:顯示屏 stdout
普通文件:普通磁盤文件
從操作系統(tǒng)的角度來看:每一個(gè)與主機(jī)相連的設(shè)備都是一個(gè)文件
文件類型結(jié)構(gòu)體 FILE.
文件信息用系統(tǒng)定義的名為FILE的結(jié)構(gòu)體描述,該結(jié)構(gòu)體定義在stdio.h中硼身,可以直接拿來用硅急。
用法:文件打開時(shí),系統(tǒng)自動(dòng)建立文件結(jié)構(gòu)體鸠姨,并把指向它的指針返回出來铜秆,程序通過這個(gè)指針獲得文件的信息,訪問文件讶迁。文件關(guān)閉后连茧,把文件結(jié)構(gòu)體釋放。
打開一個(gè)文件:
函數(shù):```FILE *fopen(char *filename,char *mode);```
功能:按指定的方式打開文件
返回值:正常打開巍糯,為指向文件(結(jié)構(gòu)體)的指針荣德;失敗触机,為NULL
>打開方式:
r:以只讀的方式打開一個(gè)文本文件
rb:以只讀的方式打開一個(gè)二進(jìn)制文件
w:...只寫..文本文件
wb:...只寫..二進(jìn)制
a:以追加的方式打開文本文件
ab:... 二進(jìn)制
r+:以讀寫的方式打開文本文件
rb+:以讀寫的方式打開二進(jìn)制文件
w+:以讀寫的方式打開文本文件
wb+:。。山孔。侦香。脖卖。窗声。二進(jìn)制文件
a+:以讀寫的方式打開文本文件
ab+:...........二進(jìn)制文件
關(guān)閉一個(gè)文件:
函數(shù):```int fclose(FILE *fp)```
功能:關(guān)閉fp指向的文件,釋放文件結(jié)構(gòu)體和文件指針
返回值: 成功厌衙,0距淫;失敗,非0
include <stdio.h>
include <stdlib.h>
void main()
{
FILE fp;
fp=fopen("3.c","a");
if(fp==NULL)
{
printf("open file is failed!\n");
exit(0);
}
int a=fclose(fp);
if(a==0)
{
printf("close is success!\n");
}
else
printf("close is failed!\n");
fp=NULL;
}
/
注:
1.若文件在當(dāng)前路徑下:
fp=fopen("文件名"婶希,"mode");
2.若文件不在當(dāng)前目錄下:
fp=fopne("文件的絕對(duì)路徑","mode");
3.若要手動(dòng)輸入要打開的文件名:
char filename[30];
scanf("%s",filename);
fp=fopen(filename,"r");
4.要對(duì)一個(gè)文件進(jìn)行操作榕暇,必須先打開這個(gè)文件,操作完成之后,必須要關(guān)閉這個(gè)文件彤枢,不關(guān)閉的話容易造成數(shù)據(jù)丟失狰晚,關(guān)閉之后使fp=NULL;
5.以r,r+的方式打開文件,若文件不存在缴啡,則打開失敗
以w,w+,a,a+的方式打開文件壁晒,若文件不存在,則會(huì)自動(dòng)創(chuàng)建文件
6.以w/w+的方式打開文件盟猖,會(huì)把文件中原有的數(shù)據(jù)清除讨衣。
7.以a/a+的方式繼續(xù)向文件中寫入數(shù)據(jù)不會(huì)覆蓋原有的數(shù)據(jù)。
*/
函數(shù):```char fputc(char ch,FILE *fp)```
功能:把一個(gè)字符ch寫到fp指向文件中
返回值:正確,返回ch式镐,錯(cuò)誤,返回EOF
>EOF:通常把它看做是一個(gè)特殊字符理解,其實(shí)在頭文件stdio.h中它是常量-1的宏定義固蚤。在linux中娘汞,它并不是一個(gè)特殊字符,只是在系統(tǒng)讀到文件結(jié)尾或者出錯(cuò)的時(shí)候所返回的一個(gè)信號(hào)值夕玩。
例:
#include <stdio.h>
void main()
{
char ch='a';
fputc(ch,stdout);
fputc('\n',stuout);
}
函數(shù):```char fgetc(FILE *fp)```
功能:從fp指向的文件中讀取一個(gè)字符
返回值:成功,返回讀到的字符你弦;當(dāng)讀到文件結(jié)尾或者出錯(cuò)的時(shí)候返回EOF
例:
include <stdio.h>
include <stdlib.h>
void main()
{
char ch=fgetc(stdin);
fputc(ch,stdout);
putchar('\n');
}
練習(xí):把一個(gè)文件中的內(nèi)容讀到另一個(gè)文件。fgetc fputc
include <stdio.h>
include <stdlib.h>
void main()
{
//分別以讀燎孟,寫的方式打開2個(gè)文件2.c 3.c
FILE *fp1=fopen("2.c","r");
FILE *fp2=fopen("3.c","w");
if(fp1==NULL)
{
printf("open 2.c is failed!\n");
exit(0);
}
if(fp2==NULL)
{
printf("open 3.c is failed!\n");
exit(0);
}
char c;
//進(jìn)行讀寫操作
while((c=fgetc(fp1))!=EOF){fputc(c,fp2);}
//關(guān)閉2個(gè)文件
int a=fclose(fp1);
int b=fclose(fp2);
if(a==0 && b==0)printf("文件關(guān)閉成功");
//指針置空
fp1=NULL;
fp2=NULL;
}
練習(xí):從鍵盤輸入一串字符禽作,把它們存到磁盤文件中去,直到輸入“?常”結(jié)束旷偿。
方法1:
include <stdio.h>
include <stdlib.h>
void main()
{
//打開磁盤文件
FILE *fp;
if((fp=fopen("2.c","w"))==NULL)
printf("open is failed!\n");
//獲取字符
char c;
while((c=getchar())!='#')
{
fputc(c,fp);
}
if(!fclose(fp))
printf("close is success!\n");
fp=NULL;
}
方法2:
include <stdio.h>
include <stdlib.h>
void main()
{
FILE *fp;
fp = fopen("4.c","w");
if(fp == NULL)
{
printf("打開失敗!\n");
exit(0);
}
char c;
while((c = fgetc(stdin)) != '#')
{
fputc(c,fp);
}
int a = fclose(fp);
if(a == 0)
{
printf("關(guān)閉成功!\n");
}
fp = NULL;
}
函數(shù):```long ftell(FILE *fp);```
功能:得知目前文件讀寫指針的位置
返回值:正確,返回目前文件讀寫指針的位置爆侣,就是當(dāng)前文件讀寫指針?biāo)诘奈恢镁嚯x文件開頭的長(zhǎng)度萍程。錯(cuò)誤,返回-1.
例:
include <stdio.h>
include <stdlib.h>
void main()
{
FILE *fp=fopen("2.c","a");
long position=ftell(fp);
printf("%ld\n",position);
}
函數(shù):```fscanf(FILE *fp,char *format,argc_list)```
功能:從fp指向的文件中按指定的格式獲取數(shù)據(jù)的輸入
返回值:成功兔仰,獲取的數(shù)據(jù)的個(gè)數(shù)茫负,失敗,EOF
例:
char name[30];
scanf("%s%d",name,&age);
例:
scanf(fp,"%s%d",name,&age);
例:
include <stdio.h>
include <stdlib.h>
void main()
{
char name[30];
int age;
fscanf(stdin,"%s%d",name,&age);
printf("name:%s age:%d\n",name,age);
}
函數(shù):```fprintf(FILE *fp,char *format,argc_list);```
功能:把數(shù)據(jù)按指定的格式輸出到指定的文件中去乎赴。
返回值:成功忍法,返回輸出項(xiàng)的個(gè)數(shù),失敗榕吼,EOF
例:
include <stdio.h>
include <stdlib.h>
void main()
{
char name[30];
int age;
fscanf(stdin,"%s%d",name,&age);
fprintf(stdout,"name:%s age:%d\n",name,age);
}
練習(xí):從鍵盤按指定的格式把數(shù)據(jù)輸入到磁盤文件中去饿序,然后又把磁盤文件中的數(shù)據(jù)讀出來顯示到屏幕上.fscanf/fprintf
include <stdio.h>
include <stdlib.h>
void main()
{
char name[30],name1[30];
int age,age1;
FILE *fp;
if((fp=fopen("3.c","w"))==NULL)
{
printf("open is failed!\n");
exit(0);
}
fscanf(stdin,"%s %d",name,&age);
fprintf(fp,"%s %d",name,age);
fclose(fp);
fopen("3.c","r");
fscanf(fp,"%s %d",name1,&age1);
fprintf(stdout,"%s %d",name1,age1);
fclose(fp);
}
函數(shù):```void rewind(FILE *fp)```
功能:讓文件指針重置在最開頭。
include <stdio.h>
include <stdlib.h>
void main()
{
char name[30],name1[30];
int age,age1;
FILE *fp;
if((fp=fopen("3.c","w+"))==NULL)
{
printf("open is failed!\n");
exit(0);
}
fscanf(stdin,"%s %d",name,&age);
fprintf(fp,"%s %d",name,age);
long position=ftell(fp);
printf("%ld\n",position);
rewind(fp);//重置指針
position=ftell(fp);
printf("%ld\n",position);
fscanf(fp,"%s %d",name1,&age1);
fprintf(stdout,"%s %d",name1,age1);
fclose(fp);
}
函數(shù):```int fseek(FILE *fp,long offset,int whence)```
功能:使fp的位置重置到指定的位置友题,從whence位置移動(dòng)offset個(gè)字符
返回值:成功為0嗤堰,失敗為-1
whence的值:
0:文件開頭
1:當(dāng)前指針?biāo)傅奈恢?2:文件的結(jié)尾
例:
fseek(fp,100L,0);將文件指針fp移到離文件頭100個(gè)字節(jié)的位置
fseek(fp,50L,1);將fp移到離當(dāng)前位置后50個(gè)字節(jié)處
fseek(fp,-10L,2);將fp從文件尾倒移10個(gè)字節(jié)。
函數(shù):```fread(addr,num數(shù)據(jù)塊的大小,count數(shù)據(jù)塊的個(gè)數(shù),fp)```
功能:從文件中讀取數(shù)據(jù)塊.從文件fp中一次讀取count個(gè)num大小的數(shù)據(jù)塊到addr內(nèi)存中踢匣。
返回值:成功告匠,返回count;失敗,返回0.
例:fread(&age,sizeof(int),1,fp);
函數(shù):```fwrite(addr,int num,int count,FILE *fp);```
功能:往文件中寫入數(shù)據(jù)塊.從地址addr中离唬,一次讀取count個(gè)num大小的數(shù)據(jù)塊到文件fp中后专。
例:fwrite(&age,sizeof(int),1,fp);
include <stdio.h>
include <stdlib.h>
void main()
{
int age=100,age1;
FILE *fp=fopen("x.c","w+");
if(fwrite(&age,sizeof(int),1,fp)==1)
//成功,返回一次讀取的數(shù)據(jù)塊的個(gè)數(shù)1输莺,失敗返回0
printf("寫入成功!\n");
rewind(fp);//重置指針的位置為開頭
if(fread(&age1,sizeof(int),1,fp)==1)
printf("讀取成功!\n");
printf("%d\n",age1);
}
練習(xí):從鍵盤輸入4個(gè)學(xué)生的個(gè)人信息戚哎,把他們存到磁盤文件中去,然后讀出來嫂用。
include <stdio.h>
include <stdlib.h>
struct student
{
char name[30];
int age;
}stu[4];
struct student stu1[4];
void main()
{
int i;
for(i=0;i<4;i++)
scanf("%s %d",stu[i].name,&stu[i].age);
FILE fp;
if((fp=fopen("student.txt","w+"))==NULL)
printf("open is failed!\n");
/
for(i=0;i<4;i++)
{
if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
printf("寫入失敗!\n");
}/
/
for(i=0;i<4;i++)
{
if(fread(&stu1[i],sizeof(struct student),1,fp)!=1)
printf("讀取失敗!\n");
}*/
if(fwrite(stu,sizeof(struct student),4,fp)!=4)
printf("寫入失敗!\n");
rewind(fp);
if(fread(stu1,sizeof(struct student),4,fp)!=4)
printf("讀取失敗!\n");
for(i=0;i<4;i++)
printf("%s %d\n",stu1[i].name,stu1[i].age);
fclose(fp);fp=NULL;
}
homework:
新建一條鏈表型凳,把鏈表里的數(shù)據(jù)讀到文件中,然后把文件中的數(shù)據(jù)讀到另一條鏈表中嘱函。