使用 <stdio.h> 頭文件中的 fopen() 函數即可打開文件,它的用法為:
FILE *fopen(char *filename, char *mode);
filename為文件名(包括文件路徑),mode為打開方式,它們都是字符串。
fopen() 函數的返回值
fopen() 會獲取文件信息,包括文件名、文件狀態、當前讀寫位置等,並將這些信息保存到一個 FILE 類型的結構體變量中,然後將該變量的地址返回。
FILE 是 <stdio.h> 頭文件中的一個結構體,它專門用來保存文件信息。我們不用關心 FILE 的具體結構,只需要知道它的用法就行。
如果希望接收 fopen() 的返回值,就需要定義一個 FILE 類型的指針。例如:
FILE *fp = fopen("demo.txt", "r");
表示以“只讀”方式打開當前目錄下的 demo.txt 文件,並使 fp 指向該文件,這樣就可以通過 fp 來操作 demo.txt 了。fp 通常被稱為文件指針。
判斷文件是否打開成功
打開文件出錯時,fopen() 將返回一個空指針,也就是 NULL,我們可以利用這一點來判斷文件是否打開成功,請看下面的代碼:
FILE *fp;
if( (fp=fopen("D:\\demo.txt","rb") == NULL ){
printf("Fail to open file!\n");
exit(0); //退出程序(結束程序)
}
fopen() 函數的打開方式
不同的操作需要不同的文件權限。例如,只想讀取文件中的數據的話,“只讀”權限就夠了;既想讀取又想寫入數據的話,“讀寫”權限就是必須的了。
另外,文件也有不同的類型,按照數據的存儲方式可以分為二進制文件和文本文件,它們的操作細節是不同的。
在調用 fopen() 函數時,這些信息都必須提供,稱為“文件打開方式”。最基本的文件打開方式有以下幾種:
|
控制讀寫權限的字符串(必須指明)
|
|
|
打開方式
|
説明
|
|
"r"
|
以“只讀”方式打開文件。只允許讀取,不允許寫入。文件必須存在,否則打開失敗。
|
|
"w"
|
以“寫入”方式打開文件。如果文件不存在,那麼創建一個新文件;如果文件存在,那麼清空文件內容(相當於刪除原文件,再創建一個新文件)。
|
|
"a"
|
以“追加”方式打開文件。如果文件不存在,那麼創建一個新文件;如果文件存在,那麼將寫入的數據追加到文件的末尾(文件原有的內容保留)。
|
|
"r+"
|
以“讀寫”方式打開文件。既可以讀取也可以寫入,也就是隨意更新文件。文件必須存在,否則打開失敗。
|
|
"w+"
|
以“寫入/更新”方式打開文件,相當於 |
|
"a+"
|
以“追加/更新”方式打開文件,相當於a和r+疊加的效果。既可以讀取也可以寫入,也就是隨意更新文件。如果文件不存在,那麼創建一個新文件;如果文件存在,那麼將寫入的數據追加到文件的末尾(文件原有的內容保留)。
|
|
控制讀寫方式的字符串(可以不寫)
|
|
|
打開方式
|
説明
|
|
"t"
|
文本文件。如果不寫,默認為 |
|
"b"
|
二進制文件。
|
調用 fopen() 函數時必須指明讀寫權限,但是可以不指明讀寫方式(此時默認為"t")。
關閉文件
文件一旦使用完畢,應該用 fclose() 函數把文件關閉,以釋放相關資源,避免數據丟失。fclose() 的用法為:
int fclose(FILE *fp);
fp 為文件指針。例如:
fclose(fp);
文件正常關閉時,fclose() 的返回值為0,如果返回非零值則表示有錯誤發生。
C語言 fread()與fwrite()函數説明與示例
1.作用
讀寫文件數據塊。
2.函數原型
(1)size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
其中,ptr:指向保存結果的指針;size:每個數據類型的大小;count:數據的個數;stream:文件指針
函數返回讀取數據的個數。
(2)size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
其中,ptr:指向保存數據的指針;size:每個數據類型的大小;count:數據的個數;stream:文件指針
函數返回寫入數據的個數。
3.注意
(1)寫操作fwrite()後必須關閉流fclose()。
(2)不關閉流的情況下,每次讀或寫數據後,文件指針都會指向下一個待寫或者讀數據位置的指針。
4.讀寫常用類型
(1)寫int數據到文件
#include <stdio.h>
#include <stdlib.h>
int main ()
{
FILE * pFile;
int buffer[] = {1, 2, 3, 4};
if((pFile = fopen ("myfile.txt", "wb"))==NULL)
{
printf("cant open the file");
exit(0);
}
//可以寫多個連續的數據(這裏一次寫4個)
fwrite (buffer , sizeof(int), 4, pFile);
fclose (pFile);
return 0;
}
View Code
(2)讀取int數據
#include <stdio.h>
#include <stdlib.h>
int main () {
FILE * fp;
int buffer[4];
if((fp=fopen("myfile.txt","rb"))==NULL)
{
printf("cant open the file");
exit(0);
}
if(fread(buffer,sizeof(int),4,fp)!=4) //可以一次讀取
{
printf("file read error\n");
exit(0);
}
for(int i=0;i<4;i++)
printf("%d\n",buffer[i]);
return 0;
}
View Code
(1)寫結構體數據到文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
int age;
char name[30];
}people;
int main ()
{
FILE * pFile;
int i;
people per[3];
per[0].age=20;strcpy(per[0].name,"li");
per[1].age=18;strcpy(per[1].name,"wang");
per[2].age=21;strcpy(per[2].name,"zhang");
if((pFile = fopen ("myfile.txt", "wb"))==NULL)
{
printf("cant open the file");
exit(0);
}
for(i=0;i<3;i++)
{
if(fwrite(&per[i],sizeof(people),1,pFile)!=1)
printf("file write error\n");
}
fclose (pFile);
return 0;
}
View Code
(2)讀結構體數據
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
int age;
char name[30];
}people;
int main () {
FILE * fp;
people per;
if((fp=fopen("myfile.txt","rb"))==NULL)
{
printf("cant open the file");
exit(0);
}
while(fread(&per,sizeof(people),1,fp)==1) //如果讀到數據,就顯示;否則退出
{
printf("%d %s\n",per.age,per.name);
}
return 0;
}
View Code
以上fwrite寫進文件裏面的是指針,如果要寫進整數或其它類型的數據,用fprintf方便一點
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp; /* 定義文件指針*/
if( ( fp = fopen("f1.txt", "w") ) == NULL){ /* 打開文件 */
printf("File open error!\n");
exit(0);
}
fprintf( fp, "%s", "Hello World! " ); /* 寫文件 */
if( fclose( fp ) ){ /* 關閉文件 */
printf( "Can not close the file!\n" );
exit(0);
}
return 0;
}
fseek
功 能: 重定位流上的文件指針
用 法: int fseek( FILE *stream, long offset, int origin );
第一個參數stream為文件指針
第二個參數offset為偏移量,整數表示正向偏移,負數表示負向偏移
第三個參數origin設定從文件的哪裏開始偏移,可能取值為:SEEK_CUR、 SEEK_END 或 SEEK_SET
其中SEEK_SET,SEEK_CUR和SEEK_END和依次為0,1和2.
簡言之:
fseek(fp,100L,0);把fp指針移動到離文件開頭100字節處;
fseek(fp,100L,1);把fp指針移動到離文件當前位置100字節處;
fseek(fp,-100L,2);把fp指針退回到離文件結尾100字節處。
描 述: 函數設置文件指針stream的位置。如果執行成功,stream將指向以fromwhere為基準,偏移offset個字 節的位置。如果執行失敗(比如offset超過文件自身大小),則不改變stream指向的位置。
返回值: 成功,返回0,否則返回其他值。
#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);
}
void 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++)
View Code
等風起的那一天,我已準備好一切