c语言总结 7:文件相关操作
-
文件打开和关闭
规定使用fopen函数打开文件,fclose函数关闭文件
FILE* fopen(const char* filename,const char* mode)//mode表示以什么形式打开
int fclose(FILE* stream) -
文件使用方式
1.“r”(只读)表示为了输入数据,打开一个已经存在的文本文件,如果指定文件不存在,则出错
2.“w”(只写)表示为了输出数据,打开一个文本文件,若指定文件不存在,则建立一个新的文件
3.“a”(追加)向文件尾添加数据
4.“rb”(只读)表示为了输入数据,打开一个二进制文件
5.“wb”(只写)表示为了输出数据,打开一个二进制文件
6.“ab”(追加)表示向一个二进制文件尾追加数据
7."r+’(读写)为了读和写,打开一个文件
8.“w+”(读写)为了读和写,建立一个文件
9.“a+”(读写)打开一个文件,在文件尾进行读和写
10.“rb+”(读写)为了读和写打开一个二进制文件
11.“wb+”(读写)为了读和写,建立一个二进制文件
12.“ab+”(读写)打开一个二进制文件,在文件尾进行读和写 -
文件顺序读写
1.字符输出函数(一个一个写入):fputc
例如:
FILE *pf = fopen("test.txt", "w");
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fclose(pf);
用只写形式打开一个文件,建立一个新的文件,结果生成一个test.txt文件,fputc函数写入字符,内容为abc.
2.字符输入函数(一个一个读):fgetc
例如:
FILE *pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
system("pause");
return 0;
}
printf("%c\n", fgetc(pf));
printf("%c\n", fgetc(pf));
printf("%c\n", fgetc(pf));
fclose(pf);
pf = NULL;
用只读形式打开上面生成的文件,用fgetc函数读字符,结果为a b c.
3.文本行输出函数:fputs(写入文本)
例如:
FILE *pf = fopen("test1.txt", "w");
fputs("zhangsan\n", pf);
fputs("lisi\n", pf);
fputs("wangwu\n", pf);
用只写形式建立一个文件,用fputs函数写入文本,结果为生成一个文件test1.txt,内容为zhangsan lisi wangwu.
4.文本行输入函数:fgets(读文本)
例如:
char buf[20] = { 0 };
FILE *pf = fopen("test1.txt", "r");
if (pf == NULL)
{
perror("fopen");
system("pause");
return 0;
}
fgets(buf, 20, pf);
printf("%s", buf);
fgets(buf, 20, pf);
printf("%s", buf);
fgets(buf, 20, pf);
printf("%s", buf);
fclose(pf);
pf = NULL;
fgets函数要将文件中的内容保存到一块空间buf中,结果为zhangsan lisi wangwu.
5.格式化输出函数 fprintf(写文件)
例如:
struct S
{
char name[20];
int age;
float i;
};
int main()
{
FILE *pf = fopen("test2.txt", "w");
struct S s = { "zhangsan", 20, 3.14f };
fprintf(pf, "%s %d %f",s.name,s.age,s.i);
fclose(pf);
pf = NULL;
return 0;
}
用只写形式建立一个test2.txt文件,用fprintf函数写入结构体的内容.
6.格式化输入函数 fscanf(读文件)
例如:
FILE *pf = fopen("test2.txt", "r");
struct S s = { 0 };
fscanf(pf,"%s %d %f", s.name, &(s.age), &(s.i));
printf("%s %d %f\n", s.name, s.age, s.i);
fclose(pf);
pf = NULL;
结果为zhangsan 20 3.140000,因为上一步写入了此内容,用只读形式打开文件,用fscanf读文件.
7.内存输出函数 sprintf(将结构体转换为字符串,涉及到内存)
例如:
struct S
{
char name[20];
int age;
double d;
};
int main()
{
struct S s = { "张三", 20, 3.54 };
char buf[30] = { 0 };
struct S tmp = { 0 };
sprintf(buf, "%s %d %lf", s.name, s.age, s.d);//将结构体转换为字符串,涉及到的是内存
printf("%s\n", buf);
return 0;
}
结果为张三 20 3.54
8.内存输入函数 sscanf
例如:
//从buf中获取一个格式化的数据,放入tmp中
sscanf(buf, "%s %d %lf", tmp.name, &(tmp.age), &(tmp.d));
printf("%s %d %lf\n", tmp.name, tmp.age, tmp.d);
结果为张三 20 3.54
9.二进制输出 fwrite (以二进制形式写入)
例如:
struct S
{
char name[20];
int age;
double d;
};
int main()
{
FILE *pf = fopen("test5.txt", "wb");
struct S s = { "zhangsan", 20, 5.6 };
if (pf == NULL)
{
perror("fopen");
return 0;
}
fwrite(&s, sizeof(struct S), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
10.二进制输入 fread(以二进制形式读)
例如:
FILE *pf = fopen("test5.txt", "rb");
struct S s = { 0 };
if (pf == NULL)
{
perror("fopen");
return 0;
}
fread(&s, sizeof(struct S), 1, pf);
printf("%s %d %f\n", s.name, s.age, s.d);
fclose(pf);
pf = NULL;
以二进制形式只读打开文件,用fread函数读出文件中的内容,为上面已经写入的zhangsan 20 5.6.
-
文件随机读写
1.fseek函数
int fseek( FILE *stream, long offset, int origin )(origin为当前文件指针位置)
例如:
FILE *pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fpoen");
return 0;
}
printf("%c\n", fgetc(pf));
/*fseek(pf, 3, SEEK_CUR);*/
/*fseek(pf, -2, SEEK_END);*///从文件末尾偏移
fseek(pf, 4, SEEK_SET);//起始位置偏移
SEEK_CUR为当前位置,SEEK_END为末尾,SEEK_SET为起始位置,例如读的文件的内容为abcdef,在第一次fgetc(pf)时读到的内容为a,如果第二次想要读到e,可以偏移3个,因此可以用fseek(pf, 3, SEEK_CUR)表示从当前位置读三个偏移量得到e,也可以用fseek(pf, -2, SEEK_END)表示从文件末尾偏移-2到e,也可以为fseek(pf, 4, SEEK_SET) 表示从起始位置偏移4个到e.
2.ftell函数(返回文件指针相对于起始位置的偏移量)
3.rewind函数
例如:
rewind(pf);
printf("%c\n", fgetc(pf));//让文件回到起始的位置
rewind函数是让文件指针回到文件的起始位置
-
文件结束判定
在文件读取过程中,不能用feof函数的返回值直接用来判断文件是否结束,而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束
判断文本文件读取是否结束,判断返回值是否为EOF(fgetc)或者NULL(fgets)
二进制文件的读取结束判断,判断返回值是否小于实际要读的个数(fread)
下一篇: Springboot2.X 静态文件配置