【C语言】文件操作(附源码与图片)
文件操作管理
- 1、文件打开
- 2、文件的顺序读写
- 2.1fputc函数
- 2.2fgetc函数
- 2.3fgets函数
- 2.4fputs函数
- 2.5fprintf函数
- 2.6fcanf函数
- 2.7sprintf函数与sscanf函数
- 2.8print与scanf大家族
- 2.9fwrite函数
- 2.10fread函数
- 3、文件的随机读写
- 3.1fseek函数
- 3.2ftell函数
- 3.3rewind
- 4、文件读取结束的判定
- 4.1被错误使用的feof
- 5、多文件复制
1、文件打开
- 文件在读写之前应该先打开文件,再使用结束之后应该关闭文件*。
- 编写程序时打开文件,都会返回应该
FILE*
的指针变量指向该文件,相当于建立了指针和文件的关系。 - 使用
fopen
函数来打开文件,fclose
来关闭文件。
//打开文件
FILE * fopen("文件名","模式");//关闭文件
int fclose(fopen);
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开应该文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本问及那尾添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开应该二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开应该二进制文件 | 建立一个新的文件 |
ab”(追加) | 向一个二进制文件尾添加数据 | 建立一个新的文件 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
w+”(读写) | 为了读和写,建立⼀个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开⼀个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
/* test.txt */
#include<stdio.h>
int main()
{//打开文件FILE *ps = ("test.txt", "w");//文件操作if(ps ! = NULL){//写文件fputs("a", ps);//关闭文件fclose(ps);}return 0;
}
2、文件的顺序读写
函数名 | 功能 | 适用于 |
---|---|---|
fgetc | 字符输入函数 | 所有输入流 |
fputc | 字符输出函数 | 所有输入流 |
fgets | 文本行输入函数 | 所有输入流 |
fputs | 文本行输出函数 | 所有输入流 |
fscanf | 格式化输入函数 | 所有输入流 |
fprintf | 格式化输出函数 | 所有输入流 |
fread | 二进制输入 | 文件输入流 |
fwrite | 二进制输出 | 文件输入流 |
上面说的适用于所有输入流一般只适用于标准输入流和其他输入流(如文件输入流);所有输出流一般适用于标准输出流和其他输出流(如文件输出流)
2.1fputc函数
int fgetc ( FILE * stream );
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main(void)
{//打开文件(存在的情况下)FILE* ps = fopen("test.txt", "w");if (ps == NULL){perror("fopen");return 1;}int ch = 0;for (ch = 'a'; ch <= 'z'; ch++){//输入字符fputc(ch, ps);}//关闭文件fclose(ps);return 0;
}
此时的test.txt文件
abcdefghijklnmopqrstuvwxyz
2.2fgetc函数
test.txt文件:
abcdefghizklmnopqrstuvwxyz
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main(void)
{//打开文件(存在的情况下)FILE* ps = fopen("test.txt", "r");if (ps == NULL){perror("fopen");return 1;}//读文件int ch = 0;while ((ch = fgetc(ps)) != EOF){printf("%c", ch);}//关闭文件fclose(ps);return 0;
}
屏幕上显示:abcdefghizklmnopqrstuvwxyz
2.3fgets函数
- 当num为10时,第10个会放\0
- 当数组过短,num过大时,会在数组后补上\n,后补\0
- fgets读取方式是一行一行的读
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main(void)
{//打开文件FILE* ps = fopen("test.txt", "r");if (ps == NULL){perror("fopen");return 1;}//读文件char arr[10] = { 0 };//最多读19个,再继续往后读,直到遇到\0再换行while (fgets(arr, 20, ps) != NULL){fgets(arr, 10, ps);}//关闭文件fclose(ps);ps = NULL;return 0;
}
2.4fputs函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main(void)
{//打开文件FILE* ps = fopen("test.txt", "w");if (ps == NULL){perror("fopen");return 1;}//写文件fputs("hello world\n", ps);fputs("hello bit\n", ps);//关闭文件fclose(ps);ps = NULL;return 0;
}
也可以打印到屏幕上,用stdout输出流
fputc('a', stdout);
2.5fprintf函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写入struct Stu s = { "张三",20,66.0 };fprintf(pf, "%s %d %f", s.name, s.age, s.score);//关闭文件fclose(pf);pf = NULL;return 0;
}
test.txt文件中显示:
张三 20 66.0
也可以打印在屏幕上,只需要用stdout输出流即可
fprintf(stdout, "%s %d %f", s.name, s.age, s.score);
屏幕上打印为:
张三 20 66.0
2.6fcanf函数
前面test.txt文本建立时,将文本里的数据拿出时,要用到fcanf来读取
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{struct Stu s = { 0 };//想从文件test.txt中读取数据放在s中FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//打印在屏幕上printf("%s %d %f", s.name, s.age, s.score);fclose(pf);pf = NULL;return 0;
}
2.7sprintf函数与sscanf函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{char buf[200] = { 0 };struct Stu s = { "张三", 20, 65.5f };//转化成字符串sprintf(buf, "%s %d %f", s.name, s.age, s.score);//以字符串的形式打印printf("1以字符串的形式:%s\n", buf); //1struct Stu t = { 0 };//读取buf字符串中的格式化的数据sscanf(buf, "%s %d %f", t.name, &(t.age), &(t.score));//以格式化形式打印printf("2以格式化打印:%s %d %f\n", t.name, t.age, t.score); //2return 0;
}
2.8print与scanf大家族
2.9fwrite函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{int arr[5] = { 0 };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}//写数据int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);fclose(pf);pf = NULL;return 0;
}
打印出乱码
2.10fread函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;float score;
};int main()
{int arr[5] = { 0 };FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//读数据fread(arr, sizeof(arr[0]), 5, pf);int i = 0;for (i = 0; i < 5; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;return 0;
}
打印的结果为:
0 0 0 0 0
3、文件的随机读写
3.1fseek函数
根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)!
test.txt文件:abcdefg
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件,移动4个字节,(SEEK_CUP)从起始位置开始fseek(pf, 4, SEEK_CUR);int ch = 0;ch = fgetc(pf);printf("%c", ch);//关闭文件fclose(pf);pf = NULL;return 0;
}
打印的结果为:e
3.2ftell函数
返回文件指针相对于起始位置的偏移量
test.txt文件:abcdefg
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件,移动4个字节,(SEEK_CUP)从起始位置开始fseek(pf, 4, SEEK_CUR);int ch = 0;ch = fgetc(pf);printf("%c\n", ch);//偏移量printf("%d\n", ftell(pf));//关闭文件fclose(pf);pf = NULL;return 0;
}
打印的结果为:
e
5
3.3rewind
让文件指针的位置回到文件的起始位置
test.txt文件:abcdefg
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件,移动4个字节,(SEEK_CUP)从起始位置开始fseek(pf, 4, SEEK_CUR);int ch = 0;ch = fgetc(pf);printf("%c\n", ch);//偏移量printf("%d\n", ftell(pf));//e//起始位移量rewind(pf);//5//读文件ch = fgetc(pf);printf("%c\n", ch);//a//关闭文件fclose(pf);pf = NULL;return 0;
}
4、文件读取结束的判定
4.1被错误使用的feof
牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否接受。
feof
的作用是:当文件读取结束的时候,判断读取结束的元素是否是:遇到文件尾结束。
- 文本文件读取是否结束,判断返回值是否为
EOF
(fgetc
),或者NULL
(fgets
)
fgetc函数:
- 如果读取正常,返回的是读取到字符的ASCLL码值
- 如果读取的过程中遇到文件末尾,或者发生错误,就返回EOF
fgets函数:
- 如果读取正常,返回的是存储读取到的字符串的字符数组的地址
- 如果读取的过程中遇到文件末尾,或者发生错误,返回NULL
- 二进制文件的读取结束判断,判断返回值是否小于世界要读的个数。
- fread判断返回值是否小于实际要读的个数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件int ch = 0;while ((ch = fgetc(pf)) != EOF){printf("%c\n", ch);}//判断是什么原因导致读取结束的if (feof(pf)){printf("文件遇到末尾,读取正常结束\n");}else if (ferror(pf)){perror("fgetc");}//关闭文件fclose(pf);pf = NULL;return 0;
}
5、多文件复制
我们要把一个文件拷贝给另一个文件,可以用到上面学过的知识
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>int main()
{FILE* pin = fopen("test.txt", "r");if (pin == NULL){perror("fopen");return 1;}FILE* pout = fopen("test2.txt", "w");if (pout == NULL){fclose(pin);pin = NULL;return 1;}int ch = 0;while ((ch = fgetc(pin)) != EOF){fputc(ch, pout);}fclose(pin);fclose(pout);pin = NULL;pout = NULL;return 0;
}