目录
文件
文件的打开和关闭
文件的使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
" r " (只读) | 为了输入数据,打卡一个已经存在的文本文件 | 出错 |
" w "(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
" a "(追加) | 向文本某位添加数据 | 建立一个新的文件 |
" rb "(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
" wb "(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
" ab "(追加) | 向一个二进制文件末尾添加数据 | 出错 |
" r+ "(读写) | 为了读和写,打开一个文本文件 | 出错 |
" w+ "(读写) | 为了读和写,建立一个新的文件 | 建立一个新的文件 |
" a+ "(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
" rb+ "(读写) | 为了读和写,打开一个二进制文件 | 出错 |
" wb+ "(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
" ab+ "() | 打开一个新的文件,在文件尾进行读和写 | 建立一个新的文件 |
打开文件时,默认打开的文件在当前文件夹内部,若要打开外部的文件,写清楚相对路径。
以只读的方式打开一个不存在的文件:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("data.txt", "r");
if (pf == NULL) {
printf("%s", strerror(errno));
return 0;
}
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
以只读的方式打开一个外部文件:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("C:\\Users\\DELL\\Desktop\\新建文件夹\\data.txt", "r");
if (pf == NULL) {
printf("%s", strerror(errno));
return 0;
}
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
文件的顺序读写
功能 | 函数名 | 适用于 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
int fgetc(FILE* stream);
// 从stream流中读取一个字符,返回这个字符的ASCII码值;如果读取失败,返回EOF
int fputc(int c, FILE* stream);
// 将c转换为字符,写在stream中
// 返回这个字符的ASCII码值;如果读取失败,返回EOF
char* fgets(char* string, int n, FILE* stream);
// 返回一个字符串,null表示错误
// 从stream中最多读取n个字符到string中
int fputs(const char* string, FILE* stream);
// 把字符串输出到stream文件中
// 如果输出成功,则返回一个非负数;若失败,返回NULL
int fscanf(FILE* stream, const char* format[, argument]...);
// 从指定的流(stream)中读取格式化的数据
// 每个函数都返回成功转换和分配的字段的数量,错误EOF
int fprintf(FILE* stream, const char* format[, argument]...);
// fprintf返回写入的字节数
// 把数据按照格式化的方式输出到指定文件流中
size_t fread(void* buffer, size_t size, size_t count, FILE* stream);
// 从stream流中读取count个数据,每个数据所占内存为size,将他们存在buffer数组中
// fread返回实际读取的完整条目的数量
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
// 把buffer中的count个数据,每个大小size,写在stream流中
// 返回值是实际写入的个数
#include <stdio.h>
typedef struct Stu
{
char name[20];
int age;
float score;
}Stu;
int main()
{
Stu s = { "张三", 20, 92.5 };
Stu tmp = { 0 };
char buffer[40];
sprintf(buffer, "%s %d %f\n", s.name, s.age, s.score);
printf(buffer);
sscanf(buffer, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
printf("%s %d %f\n", tmp.name, tmp.age, tmp.score);
return 0;
}
运行结果:
文件的随机读写
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
// data.txt:Hello World!abcdefghigklmn
FILE* pf = fopen("data.txt", "r");
if (pf == NULL) {
printf("%s\n", strerror(errno));
}
int ch = fgetc(pf);
printf("%c\n", ch); // "H"
ch = fgetc(pf);
printf("%c\n", ch); // "e"
fseek(pf, 3, SEEK_CUR); // 从当前位置偏移3,
ch = fgetc(pf);
printf("%c\n", ch); // " "
fseek(pf, -3, SEEK_END);// 从最后位置偏移3,
ch = fgetc(pf);
printf("%c\n", ch); // "l"
fseek(pf, 3, SEEK_SET);
ch = fgetc(pf);
printf("%c\n", ch); // "l"
long size = ftell(pf);
printf("%ld\n", size); // 4
rewind(pf);
ch = fgetc(pf);
printf("%c\n", ch); // H
size = ftell(pf);
printf("%ld", size); // 1
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
int i;
FILE* pf = fopen("data.txt", "w");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
for (i = 'a'; i <= 'z'; i++) {
fputc(i, pf);
}
// pf : abcdefghigklmnopqrstuvwxyz
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
int i;
long sz;
FILE* pf = fopen("data.txt", "w");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
for (i = 'a'; i <= 'z'; i++) {
fputc(i, pf);
}
// pf : abcdefghigklmnopqrstuvwxyz
fseek(pf, 3, SEEK_SET);
fputc('#', pf); // pf : abc#efghigklmnopqrstuvwxyz
sz = ftell(pf);
printf("%ld\n", sz); // 4
fseek(pf, 3, SEEK_CUR);
fputc('#', pf);// pf : abc#efg#igklmnopqrstuvwxyz
sz = ftell(pf);
printf("%ld\n", sz); // 8
fseek(pf, -25, SEEK_END);
fputc('#', pf);// pf : a#c#efg#igklmnopqrstuvwxyz
sz = ftell(pf);// 2
printf("%ld\n", sz);
rewind(pf);
fputc('#', pf);// pf : ##c#efg#igklmnopqrstuvwxyz
sz = ftell(pf);
printf("%ld\n", sz);// 1
rewind(pf);
sz = ftell(pf);
printf("%ld\n", sz);// 0
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("data.txt", "r");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
char s[100];
fgets(s, 20, pf);
printf("%s\n", s);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
char s[] = "helllo world! ni hao";
fputs(s, pf);
fputs("\nhehe\n", pf);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct Stu
{
char name[20];
int age;
double score;
}Stu;
int main()
{
FILE* pf = fopen("data.txt", "w");
Stu s = { "zhangsan", 20, 92.5 };
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
fprintf(pf, "%s %d %lf", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct Stu
{
char name[20];
int age;
double score;
}Stu;
int main()
{
FILE* pf = fopen("data.txt", "r");
Stu s = { 0 };
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
fscanf(pf, "%s %d %lf", s.name, &(s.age), &(s.score));
printf("%s %d %lf\n", s.name, s.age, s.score);
fclose(pf);
pf = NULL;
return 0;
}
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct Stu
{
char name[20];
int age;
double score;
}Stu;
int main()
{
Stu s[2] = { {"zhangsan", 20, 95.5}, {"lisi", 25, 55.5} };
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
fwrite(s, sizeof(Stu), 2, pf);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:(以二进制的形式存储)
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct Stu
{
char name[20];
int age;
double score;
}Stu;
int main()
{
Stu s[2] = { 0 };
FILE* pf = fopen("data.txt", "rb");
if (pf == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
fread(s, sizeof(Stu), 2, pf);
printf("%s %d %lf\n", s[0].name, s[0].age, s[0].score);
printf("%s %d %lf\n", s[1].name, s[1].age, s[1].score);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
将一个文件复制到另一文件
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pr = fopen("data.txt", "r");
if (pr == NULL) {
printf("open for reading :: %s\n", strerror(errno));
return 0;
}
FILE* pw = fopen("exercise.txt", "w");
if (pw == NULL) {
printf("open for wrinting :: %s\n", strerror(errno));
fclose(pr);
pr = NULL;
return 0;
}
int ch;
while ((ch = fgetc(pr)) != EOF) fputc(ch, pw);
fclose(pr);
pr = NULL;
fclose(pw);
pw = NULL;
return 0;
}
运行结果:
文本文件和二进制文件
文件读取结束的判定
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* pr = fopen("data.txt", "r");
if (!pr) {
perror("File opening failed");
return EXIT_FAILURE;
}
int c;
while ((c = fgetc(pr)) != EOF) {
putchar(c);
}
if (ferror(pr)) {
puts("I/O error when reading");
} else if (feof(pr)) {
puts("End of file reached successfully");
}
fclose(pr);
pr = NULL;
return 0;
}
int ferror(FILE* stream);
// 如果没有错误,返回0;有错误,返回非0值
int feof(FILE* stream);
// feof函数在第一次读取操作之后返回一个非零值,该操作试图读取文件的末尾。如果当前位置不是文件的结束位置,则返回0。没有错误返回。
#include <stdio.h>
#include <string.h>
#include <errno.h>
enum
{
SIZE = 5
};
int main()
{
double a[SIZE] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
FILE* pw = fopen("test.bin", "wb");
if (pw == NULL) {
printf("%s\n", strerror(errno));
return 0;
}
fwrite(a, sizeof(a[0]), SIZE, pw);
fclose(pw);
double b[SIZE];
pw = fopen("test.bin", "rb");
unsigned int sz = fread(b, sizeof(b[0]), SIZE, pw);
// fread 返回读取的个数,如果个数相等,则读取成功;
if (sz == SIZE) {
puts("Array read successfully, contents: ");
for (int i = 0; i < sz; i++) {
printf("%lf ", b[i]);
}
printf("\n");
} else {
// 当个数不相等时,可能是读取到中间结束,可能是读取错误
if (feof(pw)) {
printf("Error reading test.bin: unexpected end of file\n");
} else if (ferror(pw)) {
perror("Error reading test.bin");
}
}
fclose(pw);
pw = NULL;
return 0;
}
运行结果: