(C语言进阶)文件操作

发布时间:2024年01月20日

一.为什么使用文件

二.什么是文件

程序文件

数据文件

文件名

三.二进制文件和文本文件

测试代码:?

#include <stdio.h>
int main()
{
	int a = 10000;
	FILE* pf = fopen("text.txt","wb");	//以二进制形式写
	fwrite(&a,4,1,pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

?

?

四.文件的打开和关闭

流和标准流

标准流

文件指针

通过文件指针指向文件信息区,通过文件信息区来修改文件。

文件的打开和关闭

#include <stdio.h>
int main()
{
	int a = 10000;
	//打开文件,为了写
	//如果文件打开失败,会返回NULL
	//相对路径,在程序所在的文件路径下
	FILE* pf = fopen("text.txt","w");
	//绝对路径,加\防止编译器将其识别为转义符
	FILE* pf = fopen("C:\\Users\\zpeng\\Desktop\\dota.txt","r");
	// .表示当前目录
	// ..表示上一级路径
	FILE* pf = fopen("./../data.txt","r");//当前路径的上一级路径
	FILE* pf = fopen("./../../data.txt", "r");//当前路径的上一级路径的上一级路径
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fwrite(&a,4,1,pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

五.文件的顺序读写

顺序读写函数介绍

fputc ——写入一个字符

#include <stdio.h>
int main()
{
	FILE* pf = fopen("text.txt","w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	fputc('a',pf);
	fputc('b', pf);
	fputc('c', pf);
	fputc('d', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

#include <stdio.h>
int main()
{
	FILE* pf = fopen("text.txt","w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	for (int i = 0; i < 26; i++)
	{
		fputc('a'+i,pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

#include <stdio.h>
int main()
{
	FILE* pf = fopen("text.txt","w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	for (int i = 0; i < 26; i++)
	{
		fputc('a'+i,pf);
		fputc('\n',pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

#include <stdio.h>
int main()
{
	FILE* pf = fopen("text.txt","w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写文件
	for (int i = 0; i < 26; i++)
	{
		fputc('a'+i,stdout);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fgetc——读取一个字符

#include <stdio.h>
int main()
{
	FILE* pf = fopen("text.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//读文件
	for (int i = 0; i < 26; i++)
	{
		int c=fgetc(pf);
		printf("%c ",c);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

例子:读取data1.text的数据,写到data2.text的文件中

#include<stdio.h>
#include<stdlib.h>
int main()
{
	//打开文件
	FILE* pfread = fopen("data1.txt","r");
	if (pfread == NULL)
	{
		perror("fopen->data1.txt");
		return 1;
	}
	FILE* pfwrite = fopen("data2.txt","w");
	if (pfwrite == NULL)
	{
		fclose(pfread);	//若第二个文件打开失败,就将第一个文件关闭后退出程序
		pfread = NULL;
		perror("fopen->data2.txt");
		return 1;
	}
	//数据的读写
	int ch = 0;
	while ((ch = fgetc(pfread)) != EOF)
	{
		fputc(ch,pfwrite);
	}
	//文件的关闭
	fclose(pfread);
	fclose(pfwrite);
	pfread = NULL;
	pfwrite = NULL;
	return 0;
}

?

fputs ——写入一个字符串(不会主动换行)

#include<stdio.h>
#include<stdlib.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","w");
	if (pf == NULL)
	{
		perror("fopen->data1.txt");
		return 1;
	}
	fputs("abcdef", pf);
	fputs("abcdef", pf);
	fputs("abcdef", pf);
	fputs("abcdef", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

?

#include<stdio.h>
#include<stdlib.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","w");
	if (pf == NULL)
	{
		perror("fopen->data1.txt");
		return 1;
	}
	fputs("abcdef\n", pf);
	fputs("abcdef\n", pf);
	fputs("abcdef\n", pf);
	fputs("abcdef", pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

?

fgets——读取一个字符串(可控制读取字符串的长度)

?

#include<stdio.h>
#include<stdlib.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen->data1.txt");
		return 1;
	}
	char arr[10] = { 0 };
	fgets(arr,6,pf);//从文件中读取五个字符加一个'\0'组成字符串放在数组arr中
	printf("%s",arr);
	fclose(pf);
	pf = NULL;
	return 0;
}

?例子:由标准输入流读取一个字符串,打印在屏幕上

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int arr[10] = { 0 };
	fgets(arr,6,stdin);//从键盘中读取五个字符加一个'\0'组成字符串放在数组arr中
	fputs(arr,stdout);
	return 0;
}

?

fprintf ——文件中写入一些结构化的数据

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu S = {"zhangsan",18,90.5};
	FILE* pf = fopen("data.txt","w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fprintf(pf,"%s %d %f",S.name,S.age,S.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

?fscanf——从文件中读取一些结构化的数据

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct stu S = {0};
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fscanf(pf,"%s %d %f",S.name,&(S.age),&(S.score));
	fprintf(stdout,"%s %d %f",S.name,S.age,S.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

fwrite——以二进制形式写入?

ptr为需要写入的数据首地址,size为需要写入的数据大小,count为需要写入数据的数量,stream为被写入的文件指针?

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	//打开文件
	struct stu S = {"zhangsan",20,90.5};
	FILE* pf = fopen("data.txt","wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//二进制的写文件
	//将结构体S写入文件pf中
	fwrite(&S, sizeof(S), 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

fread——读取二进制数据?

ptr为被需要读取后存放数据的数据首地址,size为需要读取的数据大小,count为需要读取数据的数量,stream为被读取的文件指针??

#include<stdio.h>
struct stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	//打开文件
	struct stu S = {0};
	FILE* pf = fopen("data.txt","rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//二进制的读文件
	fread(&S, sizeof(S), 1, pf);
	printf("%s %d %f",S.name,S.age,S.score);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

对比一组函数

sscanf ——从一个字符串中读取一个结构化的数据

#include<stdio.h>
struct  S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = {"zhangsan",85,85.5};
	char arr[100] = {0};
	//将结构化的数据转化为字符串
	sprintf(arr,"%s %d %f",s.name,s.age,s.score);
	//从字符串中读取结构化的数据
	struct S str = { 0 };
	sscanf(arr, "%s %d %f", str.name, &(str.age), &(str.score));
	printf("%s %d %f", str.name,str.age,str.score);
	return 0;
}

?

sprintf——把结构化的数据转化成字符串?

#include<stdio.h>
struct  S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = {"zhangsan",85,85.5};
	char arr[100] = {0};
	sprintf(arr,"%s %d %f",s.name,s.age,s.score);
	printf("%s",arr);
	return 0;
}

六.文件的随机读写

fseek——调整文件中光标的位置

?

stream为文件指针,offset为偏移量,origin为指针的初始位置

SEEK_SET为从文件开头开始

SEEK_CUR为从文件当前位置开始

SEEK_END为从文件末尾开始

?

SEEK_SET——从文件开头开始

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);
	printf("%c\n",ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	//从文件开头开始
	fseek(pf,0,SEEK_SET);
	ch = fgetc(pf);
	printf("%c\n",ch);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

SEEK_CUR——从文件当前位置开始

#include<stdio.h>
int main()
{
    //打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);
	printf("%c\n",ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	//从文件当前位置开始,往前偏移四个单位
	fseek(pf,-4,SEEK_CUR);
	ch = fgetc(pf);
	printf("%c\n",ch);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

SEEK_END——从文件末尾开始

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);
	printf("%c\n",ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	//从文件末尾开始,向左偏移6个单位
	fseek(pf,-6,SEEK_END);
	ch = fgetc(pf);
	printf("%c\n",ch);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

ftell——计算当前位置相对于起始位置的偏移量

?

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);
	printf("%c\n",ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);
	
	//计算偏移量
	int n=ftell(pf);
	printf("当前偏移量为:%d",n);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

?

特殊应用:计算文件大小

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//将文件指针调整到文件末尾
	fseek(pf,0,SEEK_END);
	//计算偏移量
	int n=ftell(pf);
	printf("文件大小为:%d",n);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

rewind——将光标回到文件起始位置

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	ch = fgetc(pf);
	printf("%c\n", ch);

	//将文件光标移动到起始位置
	rewind(pf);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

七.文件读取结束的判定

feof——判断文件结束的原因是否是遇到文件末尾

ferror——判断文件结束的原因是否是遇到错误而结束?

例1:?

二进制文件的例子:?

八.文件缓冲区

?fflush——刷新缓冲区

#include<stdio.h>
#include<windows.h>
int main()
{
	FILE* pf = fopen("data.txt","w");
	//将数据放入缓冲区
	fputs("abcdef",pf);
	printf("睡眠10秒,缓冲区中已经写入数据了,打开text.txt文件,发现文件中还没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf);
	//刷新缓冲区时,才能将缓冲区中的数据写到文件中(磁盘)
	//注:ffluch在高版本的VS上已经不能使用了
	printf("再睡眠10秒,此时打开data.txt文件,文件已经有内容了\n");
	Sleep(10000);
	//关闭文件
	fclose(pf);
	//注:关闭文件时也会刷新缓冲区
	pf = NULL;
	return 0;
}

?

?

文章来源:https://blog.csdn.net/2301_79580018/article/details/135643419
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。