C语言文件操作
什么是文件
文件就是在磁盘上的一段存储空间 。
不同文件的格式是不一样的,也就是说文件存储的数据是不同的。比如 txt(文本文件) 存储的是字符数据,png(图片文件) 存储的是颜色标识数据,exe(可执行文件) 存储的都是代码。当然数据的本质都是二进制的 0和1,不同的文件在宏观上都是使用 后缀 来区分的。
所谓文件操作,就是把文件内容读进程序里,然后根据格式进行解析,进行读写等操作。
如何操作文件
一、打开文件
FILE *fopen( const char *filepath, const char *mode );
使用上面这个函数来打开一个文件。它的原理是在物理内存开辟一块空间 ,将磁盘中被选定文件的内容复制 过来(本质就是一大堆字符串),然后进行操作。当我们操作文件结束之后,再把复制的这一份更新 到磁盘空间,最终完成修改。
FILE*
fopen
const char *filepath
const char *mode
当我们对文件的操作结束后,需要在程序中关闭文件 。这一步会将我们修改后的文件更新到磁盘空间,把开辟的操作文件内存空间释放。
int fclose( FILE *stream );
二、文件的打开方式
(一)文本模式(默认的打开模式)
-
r模式:只读模式 r模式 ,又称 rt (read text) 模式,通过这种形式打开文件,文件就只能读取,不能修改。 且打开的前提要求是文件必须存在 ,不存在则打开失败,会报错。 -
w模式:可读可写模式之从头来过 w模式 ,又称 wt 模式,通过 w 模式打开的文件,首先会自动擦除原数据 。比如文件原来有内容,w 模式打开就会先把文件擦除,重新按照操作写入新数据。 而当文件不存在 的时候,会创建文件 。 -
a模式:可读可写模式之狗尾续貂 a模式 ,又称 at 模式(append),通过 a 模式打开的文件,不会擦除原有数据 ,而是在原有内容后面接着写 。比如文件有内容,打开文件内容原封不动,如果写入新内容,就会在原有的尾巴上接着写。 当文件不存在 的时候,会创建文件 。 -
三种模式的plus版本 r+模式 ( r模式plus版本 ),通过这个模式打开文件,可读可写 。所以plus之处就是加上了“写” 操作。注意前提仍然是文件必须存在。而且 r+ 模式等同 w 模式,都是擦除写。 同理,w+ 和 a+ 模式就是 w 和 a 模式的plus版本。因为plus之处在于加上“写”操作,所以plus版本和以前没什么变化。
(二)二进制模式(需要指定的模式)
-
rb模式:只读模式 rb(read bit)模式 ,原理同 rt 模式。(文件必须存在) -
wb模式:可读可写模式之从头来过 wb模式 ,原理同 wt 模式。(文件不存在会创建文件) -
ab模式:可读可写模式之狗尾续貂 ab模式 ,原理同 ab 模式。(文件不存在会创建文件) -
三种模式的plus版本 rb+模式 ( rb 模式plus版本 ),文件可读可写 。注意前提仍然是文件必须存在。而且 r+ 模式等同 w 模式,都是擦除写。 同理,wb+ 和 ab+ 模式没什么变化。
三、操作文件
(一)写
-
fwrite:一次写入指定字节数 size_t fwrite(
const void *buffer,
size_t size,
size_t count,
FILE *stream
);
举个栗子: #include <stdio.h>
#include <string.h>
int main()
{
char* str = "I LOVE YOU !";
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "w");
fwrite(str, sizeof(char), strlen(str), f);
fwrite("\n", sizeof(char), 1, f);
fwrite(str, sizeof(char), strlen(str), f);
fclose(f);
return 0;
}
-
fputs:一次写入一行(但它不会自动加换行,换行需要自己在输入字符串尾巴加\n) int fputs( const char *str, FILE *stream );
举个李子: #include <stdio.h>
#include <string.h>
int main()
{
char* str = "I LOVE YOU !";
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "w");
fputs(str, f);
fputs("\n", f);
fputs(str, f);
fclose(f);
return 0;
}
-
fprintf:格式化写入 int fprintf(
FILE *stream,
const char *format [,
argument ]...
);
举个梨子: #include <stdio.h>
#include <string.h>
int main()
{
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "w");
fprintf(f, "%d,%s,%lf", 12, "hello", 12.34);
fclose(f);
return 0;
}
(二)读(注意w和r+模式会擦除内容)
-
fread():一次读指定字节数 size_t fread(
void *buffer,
size_t size,
size_t count,
FILE *stream
);
举个例子: #include <stdio.h>
#include <string.h>
int main()
{
char str[15] = { 0 };
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "r");
fread(str, sizeof(char), 12, f);
puts(str);
fclose(f);
return 0;
}
fread()读写结构体: #include <stdio.h>
struct Node
{
int id;
char name[10];
short age;
double score;
};
int main()
{
struct Node stu1 = { 13,"张三",20,88.8 };
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "w");
fwrite(&stu1, sizeof(stu1), 1, f);
fclose(f);
struct Node stu2;
FILE* g = fopen("C:\\Users\\13040\\Desktop\\test.txt", "r");
fread(&stu2, sizeof(stu1), 1, g);
fclose(f);
return 0;
}
-
fgets():一次读一行 char *fgets( char *str, int n, FILE *stream );
举个例子: #include <stdio.h>
#include <string.h>
int main()
{
char str[20] = "";
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "r");
fgets(str, 20, f);
puts(str);
fclose(f);
return 0;
}
-
fscanf():格式化读(与fprintf配套使用) int fscanf(
FILE *stream,
const char *format [,
argument ]...
);
举个例子: #include <stdio.h>
#include <string.h>
int main()
{
int a = 0;
char str[20] = { 0 };
double b = 0;
FILE* f = fopen("C:\\Users\\13040\\Desktop\\test.txt", "r");
fscanf(f, "%d,%s %lf", &a, str, &b);
printf("%d\n", a);
printf("%s\n", str);
printf("%lf", b);
fclose(f);
return 0;
}
(三)文件游标指针
为了对读写进行控制,系统为每一个文件设置了一个文件读写游标指针(或称文件读写位置标记),用来指示“接下来要读写的下一个字符的位置”。
一般情况下,在对文本文件进行顺序读写时,文件游标指针指向文件开头,这时进行读操作,就读第一个字符,然后文件游标指针向后移动一个位置,以此类推,遇到文件尾结束。
如果是写操作,则每写完一个数据后,文件游标指针顺序向后移动一个位置,然后下一次写操作时把数据写入新的所指位置,以此类推,直到写完全部数据。
也可以根据需要,人为移动游标指针位置。
-
feof判断文件的游标指针是否位于文件结尾处 int feof( FILE *stream );
-
fseek设置文件游标指针的位置 int fseek(
FILE *stream,
long offset,
int origin
);
巨蟹李子: fseek(f, 0L, SEEK_SET)
fseek(f, 10L, SEEK_SET)
fseek(f, 10L, SEEK_CUR)
fseek(f, -10L, SEEK_CUR)
fseek(f, 0L, SEEK_END)
fseek(f, -10L, SEEK_END)
-
ftell返回文件游标指针的当前位置 long ftell(
FILE *stream
);
|