一、fopen
fopen函數用於打開文件, 其調用格式為:FILE *fopen(char *filename, *type);
fopen()函數中第一個形式參數表示文件名, 可以包含路徑和文件名兩部分。
格式:“B:TEST.DAT"或者"C:\\TC\\TEST.DAT"
fopen函數用來打開一個文件,其調用的一般形式為: 文件指針名=fopen(文件名,使用文件方式)
其中,“文件指針名”必須是被說明為FILE 類型的指針變量,“文件名”是被打開文件的文件名。
“使用文件方式”是指文件的類型和操作要求。“文件名”是字符串常量或字符串數組。例如:
FILE *fp;
fp = ("file a","r");
其意義是在當前目錄下打開文件file a, 只允許進行“讀”操作,並使fp指向該文件。
又如:
FILE *fphzk
fphzk=("c:\\hzk16","rb")
其意義是打開C驅動器磁盤的根目錄下的文件hzk16, 這是一個二進制文件,只允許按二進制方式進行讀操作。
兩個反斜線“\ ”中的第一個表示轉義字符,第二個表示根目錄。使用文件的方式共有12種,下面給出了它們的符號和意義。
第二個形式參數表示打開文件的類型。關於文件類型的規定參見下表。
| 字符 | 含義 |
|---|---|
| r | 打開文件只讀 |
| w | 打開文件只寫 |
| a | 增補,如果文件不存在創建一個 |
| r+ | 打開一個文字文件讀/寫 |
| w+ | 創建一個文字文件讀/寫 |
| a+ | 打開或創建一個文件增補 |
| b | 二進制文件(可以和上面每一項合用) |
| rb | 只讀打開一個二進制文件,只允許讀數據 |
| wb | 只寫打開或建立一個二進制文件,只允許寫數據 |
| ab | 追加打開一個二進制文件,並在文件末尾寫數據 |
| rt+ | 讀寫打開一個文本文件,允許讀和寫 |
| wt+ | 讀寫打開或建立一個文本文件,允許讀寫 |
| at+ | 讀寫打開一個文本文件,允許讀,或在文件末追加數據 |
| rb+ | 讀寫打開一個二進制文件,允許讀和寫 |
| wb+ | 讀寫打開或建立一個二進制文件,允許讀和寫 |
| ab+ | 讀寫打開一個二進制文件,允許讀,或在文件末追加數據 |
對於文件使用方式有以下幾點說明:
- 文件使用方式由r,w,a,t,b,+六個字符拼成,各字符的含義是:
r(read): 讀
w(write): 寫
a(append): 追加
t(text): 文本文件,可省略不寫
b(banary): 二進制文件
+: 讀和寫 - 凡用“r”打開一個文件時,該文件必須已經存在, 且只能從該文件讀出。
- 用“w”打開的文件只能向該文件寫入。 若打開的文件不存在,則以指定的文件名建立該文件,若打開的文件已經存在,則將該文件刪去,重建一個新文件。
- 若要向一個已存在的文件追加新的信息,只能用“a”方式打開文件。
- 在打開一個文件時,如果出錯,fopen將返回一個空指針值NULL。在程序中可以用這一信息來判別是否完成打開文件的工作,並作相應的處理。因此常用以下程序段打開文件:
if((fp=fopen("c:\\hzk16","rb")==NULL)
{
printf("\nerror on open c:\\hzk16 file!");
getch();
exit(1);
}
這段程序的意義是,如果返回的指針為空,表示不能打開C盤根目錄下的hzk16文件,則給出提示信息 “error on open c:\ hzk16file!”,下一行getch()的功能是從鍵盤輸入一個字符,但不在屏幕上顯示。在這里,該行的作 用是等待, 只有當用戶從鍵盤敲任一鍵時,程序才繼續執行, 因此用戶可利用這個等待時間閱讀出錯提示。敲鍵后執行exit(1)退出程序。
- 把一個文本文件讀入內存時,要將ASCII碼轉換成二進制碼, 而把文件以文本方式寫入磁盤時,也要把二進制碼轉換成ASCII碼,因此文本文件的讀寫要花費較多的轉換時間。對二進制文件的讀寫不存在這種轉換。
- 標准輸入文件(鍵盤),標准輸出文件(顯示器 ),標准出錯輸出(出錯信息)是由系統打開的,可直接使用。文件關閉函數fclose文件一旦使用完畢,應用關閉文件函數把文件關閉, 以避免文件的數據丟失等錯誤。
二、fclose
fclose()函數用來關閉一個由fopen()函數打開的文件 。
其調用格式為: int fclose(FILE *stream); 該函數返回一個整型數。當文件關閉成功時, 返回0, 否則返回一個非零值。可以根據函數的返回值判斷文件是否關閉成功。
FILE *fpOut=fopen("c:\\a.txt","wt+");
int a=1;
fprintf(fpOut,"%d",a);
fclose(fpOut);
當前指針不是null 是0 注意
三、fread與fwrite
- 作用
讀寫文件數據塊。
- 函數原型
(1)size_t fread ( void * ptr, size_t size, size_t nmemb, FILE * stream );
其中,ptr:指向保存結果的指針;size:每個數據類型的大小;count:數據的個數;stream:文件指針函數返回讀取數據的個數。
(2)size_t fwrite ( const void * ptr, size_t size, size_t nmemb, FILE * stream );
其中,ptr:指向保存數據的指針;size:每個數據類型的大小;count:數據的個數;stream:文件指針
函數返回寫入數據的個數。
- 注意
(1)寫操作fwrite()后必須關閉流fclose()。
(2)不關閉流的情況下,每次讀或寫數據后,文件指針都會指向下一個待寫或者讀數據位置的指針。
返回值:讀或寫的記錄數,成功時返回的記錄數等於nmemb,出錯或讀到文件末尾時返回的記錄
數小於nmemb,也可能返回0。
fread和fwrite用於讀寫記錄,這里的記錄是指一串固定長度的字節,比如一個int、一個結構體或者一個定長數組。參數size指出一條記錄的長度,而nmemb指出要讀或寫多少條記錄,這些記錄在ptr所指的內存空間中連續存放,共占size * nmemb個字節,fread從文件stream中讀出size * nmemb個字節保存到ptr中,而fwrite把ptr中的size * nmemb個字節寫到文件stream中。
nmemb是請求讀或寫的記錄數,fread和fwrite返回的記錄數有可能小於nmemb指定的記錄數。例如當前讀寫位置距文件末尾只有一條記錄的長度,調用fread時指定nmemb為2,則返回值為1。如果當前讀寫位置已經在文件末尾了,或者讀文件時出錯了,則fread返回0。如果寫文件時出錯了,則fwrite的返回值小於nmemb指定的值。
四、fseek
int fseek(FILE *stream, long int offset, int whence) 設置流 stream 的文件位置為給定的偏移 offset,參數 offset 意味着從給定的 whence 位置查找的字節數。
參數
-
stream -- 這是指向 FILE 對象的指針,該 FILE 對象標識了流。
-
offset -- 這是相對 whence 的偏移量,以字節為單位。
-
whence -- 這是表示開始添加偏移 offset 的位置。它一般指定為下列常量之一:
常量 描述 SEEK_SET 件的開頭 SEEK_CUR 文件指針的當前位置 SEEK_END 文件的末尾 fseek(fp,100L,0);把fp指針移動到離文件開頭100字節處;
fseek(fp,100L,1);把fp指針移動到離文件當前位置100字節處;
fseek(fp,-100L,2);把fp指針退回到離文件結尾100字節處。 -
返回值
如果成功,則該函數返回零,否則返回非零值。
#include <stdio.h>
#define N 5
typedef struct student {
long sno;
char name[10];
float score[3];
} STU;
void fun(char *filename, STU n)
{
FILE *fp;
fp = fopen(filename, "rb+");
fseek(fp, -1L*sizeof(STU),SEEK_END);
fwrite(&n, sizeof(STU), 1, fp);
fclose(fp);
}
int main()
{
STU t[N]={ {10001,"MaChao", 91, 92, 77}, {10002,"CaoKai", 75, 60, 88},
{10003,"LiSi", 85, 70, 78}, {10004,"FangFang", 90, 82, 87},
{10005,"ZhangSan", 95, 80, 88}};
STU n={10006,"ZhaoSi", 55, 70, 68}, ss[N];
int i,j; FILE *fp;
fp = fopen("student.dat", "wb");
fwrite(t, sizeof(STU), N, fp);
fclose(fp);
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
printf("\nThe original data :\n\n");
for (j=0; j<N; j++)
{
printf("\nNo: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name);
for (i=0; i<3; i++)
printf("%6.2f ", ss[j].score[i]);
printf("\n");
}
fun("student.dat", n);
printf("\nThe data after modifing :\n\n");
fp = fopen("student.dat", "rb");
fread(ss, sizeof(STU), N, fp);
fclose(fp);
for (j=0; j<N; j++)
{
printf("\nNo: %ld Name: %-8s Scores: ",ss[j].sno, ss[j].name);
for (i=0; i<3; i++)
printf("%6.2f ", ss[j].score[i]);
printf("\n");
}
}
The original data :
No: 10001 Name: MaChao Scores: 91.00 92.00 77.00
No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00
No: 10003 Name: LiSi Scores: 85.00 70.00 78.00
No: 10004 Name: FangFang Scores: 90.00 82.00 87.00
No: 10005 Name: ZhangSan Scores: 95.00 80.00 88.00
The data after modifing :
No: 10001 Name: MaChao Scores: 91.00 92.00 77.00
No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00
No: 10003 Name: LiSi Scores: 85.00 70.00 78.00
No: 10004 Name: FangFang Scores: 90.00 82.00 87.00
No: 10006 Name: ZhaoSi Scores: 55.00 70.00 68.00
五、fprintf與fscanf
fprintf:傳送格式化輸出到一個文件中
函數原型:int fprintf(FILE stream, char format[, argument,...]);
FILE 一個FILE型的指針
char 格式化輸入函數,和printf里的格式一樣
返回值:成功時返回轉換的字節數,失敗時返回一個負數
#include<stdio.h>
#include<iostream>
int main()
{
FILE* f = fopen("C:\\1.txt","a+");
char str[6] = "hello";
fprintf(f,"%s\n",str);
fclose(f);
}
fscanf:從一個流中執行格式化輸入
函數原型:int fscanf(FILE stream, char format[,argument...]);
FILE 一個FILE型的指針
char 格式化輸出函數,和scanf里的格式一樣
返回值:成功時返回轉換的字節數,失敗時返回一個負數
#include<stdio.h>
#include<iostream>
int main()
{
long dev;
long offset;
long length;
char ch;
double ts=0.000000;
FILE* fd = fopen("C://1.txt","r");
if(5 == fscanf(fd,"%ld,%ld,%ld,%c,%lf\n",&dev,&offset,&length,&ch,&ts))
{
printf("%ld,%ld,%ld,%c,%lf\n",dev,offset,length,ch,ts);
}
fclose(fd);
return 0;
}
六、feof
檢查文件流是否讀到了文件尾)
int feof(FILE * stream);
函數說明 feof()用來偵測是否讀取到了文件尾,尾數stream為fopen()所返回之文件指針。如果已到文件尾則返回非零值,其他情況返回0。
返回值 返回非零值代表已到達文件尾。
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
fp = fopen("file.txt","r");
if(fp == NULL)
{
perror("打開文件時發生錯誤");
return(-1);
}
while(1)
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}
fclose(fp);
return(0);
}
七、fgetc與fputc
定義函數 int fgetc(FILE * stream);
從指定的流 stream 獲取下一個字符(一個無符號字符),並把位置標識符往前移動。若讀到文件尾而無數據時便返回EOF。
#include <stdio.h>
int main ()
{
FILE *fp;
int c;
int n = 0;
fp = fopen("file.txt","r");
if(fp == NULL)
{
perror("打開文件時發生錯誤");
return(-1);
}
do
{
c = fgetc(fp);
if( feof(fp) )
{
break ;
}
printf("%c", c);
}while(1);
fclose(fp);
return(0);
}
int fputc(int c,FILE * stream);
fputc 會將參數c 轉為unsigned char 后寫入參數stream 指定的文件中。
返回值 fputc()會返回寫入成功的字符,即參數c。若返回EOF則代表寫入失敗。
#include <stdio.h>
int main ()
{
FILE *fp;
int ch;
fp = fopen("file.txt", "w+");
for( ch = 33 ; ch <= 100; ch++ )
{
fputc(ch, fp);
}
fclose(fp);
return(0);
}
八、fgets與fputs
char * fgets(char * s,int size,FILE * stream);
函數說明 fgets()用來從參數stream所指的文件內讀入字符並存到參數s所指的內存空間,直到出現換行字符、讀到文件尾或是已讀了size-1個字符為止,最后會加上NULL作為字符串結束。
返回值 gets()若成功則返回s指針,返回NULL則表示有錯誤發生。
#include <stdio.h>
int main()
{
FILE *fp;
char str[60];
/* 打開用於讀取的文件 */
fp = fopen("file.txt" , "r");
if(fp == NULL) {
perror("打開文件時發生錯誤");
return(-1);
}
if( fgets (str, 60, fp)!=NULL ) {
/* 向標准輸出 stdout 寫入內容 */
puts(str);
}
fclose(fp);
return 0;
}
int fputs(const char * s,FILE * stream);
fputs()用來將參數s所指的字符串寫入到參數stream所指的文件內。
返回值 若成功則返回寫出的字符個數,返回EOF則表示有錯誤發生。
#include <stdio.h>
int main ()
{
FILE *fp;
fp = fopen("file.txt", "w+");
fputs("1", fp);
fputs("2", fp);
fclose(fp);
return(0);
}
九、freopen
定義函數 FILE * freopen(const char * path,const char * mode,FILE * stream);
函數說明 參數path字符串包含欲打開的文件路徑及文件名,參數mode請參考fopen()說明。參數stream為已打開的文件指針。Freopen()會將原stream所打開的文件流關閉,然后打開參數path的文件。
返回值 文件順利打開后,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,並把錯誤代碼存在errno 中。
#include <stdio.h>
int main(){
FILE * fp;
fp=fopen("C://1.txt","r");
fp=freopen("C://2.txt","r",fp);
fclose(fp);
return 0;
}
十、ftell
long ftell(FILE * stream);
函數說明 ftell()用來取得文件流目前的讀寫位置。參數stream為已打開的文件指針。
返回值 當調用成功時則返回目前的讀寫位置,若有錯誤則返回-1,errno會存放錯誤代碼。
#include <stdio.h>
int main ()
{
FILE *fp;
int len;
fp = fopen("file.txt", "r");
if( fp == NULL )
{
perror ("打開文件錯誤");
return(-1);
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fclose(fp);
printf("file.txt 的總大小 = %d 字節\n", len);//19
return(0);
}
