C语言—文件操作
1.1 fgetc() + fputc(): 以 字符 形式存取数据定义文件指针
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
using namespace std;
/*
文件结束标志: EOF --- feof()
读写文件:
fgetc: file get char 以字符形式获取
fputc: file put char 以字符形式写到文件
*/
int main()
{
//定义文件指针
FILE *fp;
//打开文件
fp = fopen("fopen_01.txt", "w+");
//判断文件打开是否成功
if (!fp) {
printf("打开文件失败
");
exit(0);
}
//写的方式: 自己移动
fputc('a', fp);
fputc('b', fp);
fputc('c', fp);
//打开文件
fclose(fp);
//只读文件
FILE *read = fopen("fopen_01.txt", "r");
if (!read) {
printf("打开文件失败
");
exit(0);
}
//读文件
//fgetc(): 放回int值, 以字符形式获取
int ch = fgetc(read);
while (ch != EOF)
{
putchar(ch); //打印字符到命令行
ch = fgetc(read);
}
printf("
");
fclose(read);
return 0;
}
2.2 fgets() + fputs(): 以 字符串 形式存取数据
#define _CRT_SECURE_NO_WARNINGS
#include <cstdlib>
#include <cstdio>
using namespace std;
/*
int fputs(char *str, FILE *fp);
char* fgets(char *str, int n, FILE *fp);
*/
int main()
{
FILE *fp = fopen("fgets_fputs_02.txt", "w+");
if (!fp) {
printf("打开文件失败");
exit(1);
}
//写的方式: 自己移动
int isok = fputs("Douzi is cute
I love china!
who are you?", fp);
//返回非负值,表示成功
printf("返回非负值表示成功: %d
", isok);
fclose(fp);
FILE *read = fopen("fgets_fputs_02.txt", "r");
if (!read) {
printf("打开文件失败
");
exit(1);
}
//读文件
char str[50] = "";
//设置读取的长度
while (fgets(str, 50, read))
{
puts(str);
}
//puts(str);
fclose(read);
return 0;
}
2.3 fread() + fwrite(): 以 二进制 形式存取数据
2.3.1 结构体数据
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
/*
//以二进制形式存储数据
int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)
//以什么方式写进去就以什么方式读出 !!
int fread(void *buffer,unsigned size, unsigned count, FILE * fp)
*/
struct student
{
char name[20];
int age;
double num;
}mystudent;
int main()
{
//写文件
FILE *fp = fopen("fread_fwrite_03.bat", "wb");
if (fp == NULL) {
printf("打开失败
");
exit(1);
}
while (true)
{
printf("输入姓名-年龄-成绩:
");
scanf("%s%d%lf", &mystudent.name, &mystudent.age, &mystudent.num);
//参数: 源起始位置, 写多少(字节), 写的次数, 目的地
// &mystudent, sizeof(struct student), 1, fp
fwrite(&mystudent, sizeof(struct student), 1, fp);
printf("是否继续?(Y/N)");
//清除缓冲区
//否则下面的字符无法输入,因为上面输入按下回车,"回车"会被下面的getchar()吃掉,而无法自己输入
fflush(stdin);
int ch = getchar();
if (ch == 'N' || ch == 'n') {
break;
}
}
fclose(fp);
//读取文件
FILE *read = fopen("fread_fwrite_03.bat", "rb");
if (!read) {
printf("文件打开失败
");
exit(1);
}
//以二进制形式读取
while (fread(&mystudent, sizeof(struct student), 1, read) > 0) {
printf("姓名 年龄 成绩:
");
printf("%s %d %.2f
", mystudent.name, mystudent.age, mystudent.num);
}
fclose(read);
return 0;
}
2.3.2 结构体数组
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
/*
//以二进制形式存储数据
int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)
//以什么方式写进去就以什么方式读出 !!
int fread(void *buffer,unsigned size, unsigned count, FILE * fp):
count: 知道有多少数据可以读取
*/
const int maxn = 1024 + 10;
struct student
{
char name[20];
int age;
double num;
}stus[maxn];
int main()
{
////写文件
FILE *fp = fopen("fread_fwrite_03.bat", "wb");
if (fp == NULL) {
printf("打开失败
");
exit(1);
}
int cnt;
scanf("%d", &cnt);
for (int i = 0; i < cnt; i++)
{
printf("输入姓名-年龄-成绩:
");
scanf("%s%d%lf", &stus[i].name, &stus[i].age, &stus[i].num);
//清除缓冲区
//否则下面的字符无法输入,因为上面输入按下回车,"回车"会被下面的getchar()吃掉,而无法自己输入
fflush(stdin);
}
//参数: 源起始位置, 写多少(字节), 写的次数, 目的地
// stus, sizeof(struct student), cnt, fp
fwrite(stus, sizeof(struct student), cnt, fp);
fclose(fp);
//读取文件
FILE *read = fopen("fread_fwrite_03.bat", "rb");
if (!read) {
printf("文件打开失败
");
exit(1);
}
student read_demo[maxn];
fread(read_demo, sizeof(struct student), cnt, read);
for (int i = 0; i < cnt; i++){
printf("姓名 年龄 成绩:
");
printf("%s %d %.2f
", read_demo[i].name, read_demo[i].age, read_demo[i].num);
}
return 0;
}
2.4 fprintf() + fscanf():模式化读写文件数据
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
using namespace std;
/*
//printf: 多了指定位置
//参数: 指定位置, 与printf一样的格式化【类似%d这样】, 参数列表
int fscanf(FILE *fp, char *format, arg_list);
int fprintf(FILE *fp, char *format, arg_list);
stdin: 标准输入 -- 键盘输入
stdout: 标准输出 -- 屏幕输出
FILE *: 自定义输入输出
*/
const int maxn = 20;
struct Student
{
char name[maxn];
int age;
double score;
} mystu, stu[maxn];
int main()
{
//写文件
////标准输入输出
//printf("请输入姓名,年龄,成绩:
");
//fscanf(stdin, "%s%d%lf", mystu.name, &mystu.age, &mystu.score);
//fprintf(stdout, "%s %d %.1f
", mystu.name, mystu.age, mystu.score);
FILE *fp = fopen("fscanf_fprintf_04.txt", "w+");
if (!fp) {
printf("failure!
");
exit(1);
}
while (true)
{
printf("输入姓名-年龄-成绩:
");
//标准输入,写入文件
fscanf(stdin, "%s%d%lf", mystu.name, &mystu.age, &mystu.score);
//写入文件
fprintf(fp, "%s %d %.2f
", mystu.name, mystu.age, mystu.score);
fflush(stdin);
printf("是否继续?(Y/N)");
int ch = getchar();
if (ch == 'N' || ch == 'n') {
break;
}
}
fclose(fp);
//读文件
FILE *read = fopen("fscanf_fprintf_04.txt", "r+");
if (!read) {
printf("failure
");
exit(1);
}
while (fscanf(read, "%s%d%lf", mystu.name, &mystu.age, &mystu.score) > 0)
{
//标准输出
fprintf(stdout, "%s %d %.2f
", mystu.name, mystu.age, mystu.score);
}
fclose(read);
}
3.1 文件指针: fseek() + rewind()
-
ftell(fp): 现在所在位置(可用来求数据个数)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
/*
fseek: fseek(文件类型指针, 位移量, 起始点) 位移量必须是long类型
起始点: (宏)
SEEK_SET 文件首 0;
SEEK_CUR 文件当前位置 1;
SEEK_END 文件尾部 2;
以二进制形式存储数据
int fwrite(void *buffer,unsigned size, unsigned count, FILE * fp)
//以什么方式写进去就以什么方式读出 !!
int fread(void *buffer,unsigned size, unsigned count, FILE * fp)
*/
struct Student
{
char name[20];
int age;
double num;
}stus[20];
int main()
{
//以二进制形式写文件
FILE *fp = fopen("fseek_rewind_06.txt", "wb+");
if (!fp) {
printf("failure!
");
exit(1);
}
int N;
cin >> N;
for (int i = 0; i < N; i++)
{
printf("输入姓名-年龄-分数:
");
scanf("%s%d%lf", stus[i].name, &stus[i].age, &stus[i].num);
fflush(stdin);
}
//写入文件
//存N个数据
fwrite(stus, sizeof(struct Student), N, fp);
//fseek(文件类型指针, 位移量, 起始点) 位移量必须是long类型
//SEEK_SET 文件首 0;
//注意点: 移动多个位置, long L :表示
//正负: 往后- 往前+
fseek(fp, 0, SEEK_SET);
//移动到第二个数据位置
Student tmp;
fseek(fp, 1L * sizeof(struct Student), SEEK_SET);
fread(&tmp, sizeof(struct Student), 1, fp);
printf("第二个数据:
");
printf("%s %d %.2f
", tmp.name, tmp.age, tmp.num);
//移动到最后一个位置(之后无元素)
fseek(fp, 0, SEEK_END);
long size = ftell(fp); //ftell:现在所在位置(表达这个文件的大小)
int number = size / sizeof(Student);
printf("有几个数据%d:
", number);
//移动到最后一个元素之前位置 位移量必须是long类型,需要类型转换
fseek(fp, -1L * (long)sizeof(struct Student), SEEK_END);
fread(&tmp, sizeof(struct Student), 1, fp);
printf("最后一个元素:
");
printf("%s %d %.2f
", tmp.name, tmp.age, tmp.num);
//直接移动到文件开始位置
Student stu[20];
rewind(fp);
printf("全部数据:
");
int len = fread(stu, sizeof(struct Student), N, fp);
for (int i = 0; i < len; i++){
printf("%s %d %.2f
", stu[i].name, stu[i].age, stu[i].num);
}
fclose(fp);
return 0;
}