C语言中文件操作,即文件打开,文件写入、文件读取、文件关闭等。
在使用这些功能时,需要了解其基本的使用规则,如:
文件读写前,必须先使用fopen函数打开文件。
使用fopen打开时,还要指明文件的打开的参数,是要读呢还是写呢?这些参数如果不注意,比如直接使用”w”参数打开一个已存在的文件,则里面的内容会先被清空,如果还想要之前的文件中的内容,那也已经被清空了!
文件操作基础函数
fopen
若要对文件进行读写操作,第一步需要使用fopen()函数
fopen()函数用于打开指定路径的文件,获取指向该文件的指针
函数原型:
1 2 3 4 5 6 7 8
|
FILE * fopen(const char * path,const char * mode);
|
fopen打开方式的参数
打开文件的参数,一共6种符号,包括2部分,第1部分的指定读还是写(r\w\a),第2部分指定是对第1部分的补充(t/b/+)
| 第1部分字符 |
含义 |
解释 |
| r |
read |
只读(打开文件),文件必须存在 |
| w |
write |
只写(创建文件),文件若已存在,则文件会先被清空 |
| a |
append |
末尾追加写入,文件若不存在,则先创建 |
| 第2部分字符 |
含义 |
解释 |
| t |
text |
读写文本文件 |
| b |
binary |
读写二进制文件 |
| + |
read/write |
即能读也能写 |
注意:
参数第1部分的必须要有的,第2部分可以省略,但省略后,会有其默认的含义
未指明是读文本还是二进制,则默认为读文本文件
默认规则:
1 2 3 4 5 6
| "r" = "rt", 因为默认打开text "w" = "wt", 因为默认打开text "a" = "at", 因为默认打开text "r+" = "rt+", 因为默认打开text "w+" = "wt+", 因为默认打开text "a+" = "at+", 因为默认打开text
|
思考:
r表示读,w表示写,都补充一个+,表示既能读也能写,看起来作用好像是一样
但,区别就在于第1部分的r与w,一个是文件必须存在,一个是不存在则会先创建
- 疑问2:
w与w+的作用有区别吗?a与a+的作用有区别吗?
w表示擦除写入,a表示追加写入,都补充一个+,赋予它们读的功能
w和a既然都能写了,还不能读吗,还要添加一个+才能读?是的!
fread
函数原型:
1 2 3 4 5 6 7 8 9
|
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
|
fread的返回值随着调用格式的不同而不同:
调用格式1:fread(buf,sizeof(buf),1,fp);,将整个buf数据作为1个数据读取,则读取的个数是1
读取成功返回值为1
调用格式2:fread(buf,1,sizeof(buf),fp);,将1Byte作为1个数据读取,则读取个数是sizeof(buf)
读取成功返回实际写入的数据个数(单位为Byte)
fwrite
fwrite()函数用于将内存区域中的数据写入到本地文本
函数原型:
1 2 3 4 5 6 7 8 9
|
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
|
fwrite的返回值随着调用格式的不同而不同:
- 调用格式1:
fwrite(buf,sizeof(buf),1,fp);,将整个buf数据作为1个数据写入,则写入个数是1
成功写入返回值为1
- 调用格式2:
fwrite(buf,1,sizeof(buf),fp);,将1Byte作为1个数据写入,则写入个数是sizeof(buf)
成功写入则返回实际写入的数据个数(单位为Byte)
fclose
写完数据后要调用fclose()关闭流,不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。
函数原型:
1 2 3 4 5 6
|
int fclose( FILE *stream );
|
使用示例
基础示例
打开&写入
小技巧:
用malloc函数申请区域时是申请的一片char*区域,通过强制类型转换后可装任意类型数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <stdio.h> #include <stdlib.h>
#define DATA_SIZE 100 int main() { unsigned char *pRawData = NULL; int *pData = NULL; pRawData = (unsigned char *)malloc(sizeof(int) * DATA_SIZE); pData = (int *) pRawData; int i = 0; for(i=0; i<DATA_SIZE; i++) { pData[i] = i; } FILE *fp = fopen("../test1.bin","wb"); if(NULL == fp) { printf("open file fail\r\n"); goto end; } size_t cnt = fwrite(pData, sizeof(int), DATA_SIZE, fp); if(DATA_SIZE != cnt) { printf("write file fail\r\n"); fclose(fp); goto end; } fclose(fp); printf("file write ok\r\n"); end: free(pRawData); system("pause"); return 0; }
|
打开&读取
注意:
以2进制的形式写入,读取时也必须是以2进制形式读取!否则会读取到错误的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <stdio.h> #include <stdlib.h>
#define DATA_SIZE 100 int main() { int pData[DATA_SIZE]; FILE *fp = fopen("../test1.bin","rb"); if(NULL == fp) { printf("open file fail\r\n"); goto end; } size_t cnt = fread(pData, sizeof(int), DATA_SIZE, fp); if(DATA_SIZE != cnt) { printf("read file fail, read size:%d\r\n", cnt); fclose(fp); goto end; } printf("data[30]:%d\r\n", pData[30]); fclose(fp); printf("file read ok\r\n"); end: system("pause"); return 0; }
|
特殊示例
写入结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| typedef struct { char name[256]; unsigned int page; float price; }BOOK;
BOOK book1 = { .name = "C语言基础", .page = 320, .price = 25.0, };
|
写入方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| FILE *fp1 = fopen("../test2.bin","wb"); if(NULL == fp1) { printf("open file fail\r\n"); goto end; }
size_t cnt1 = fwrite(&book1, 1, sizeof(BOOK), fp1); if(sizeof(BOOK) != cnt1) { printf("write file fail\r\n"); fclose(fp1); goto end; }
|
读取方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| FILE *fp2 = fopen("../test2.bin","rb"); if(NULL == fp2) { printf("open file fail\r\n"); goto end; }
size_t cnt2 = fread(&myBook, 1, sizeof(BOOK), fp2); if(sizeof(BOOK) != cnt2) { printf("read file fail\r\n"); fclose(fp2); goto end; } printf("myBook info: name:%s, page:%d, price:%.2f\r\n", myBook.name, myBook.page, myBook.price);
|
总结
读(fread)或写(fwrite)文件前,要先打开(fopen)文件。
读(fread)或写(fwrite)文件后,要关闭(fclose)文件。
打开(fopen)文件时,要特别注意打开的参数指定。
带r参数打开文件时,该文件必须存在。
带w参数打开文件时,该文件会被先清空,若文件不存在会先创建。
带a参数打开文件时,写入内容将会在文件尾部添加,若文件不存在会先创建。
带b参数打开文件时,打开的是二进制文件。
带t参数打开文件时,或不指明b或t,则打开的是文本文件。
带+参数打开文件时,就有了读与写的功能。