【C语言】文件操作详解

 2024-02-11 03:03:35  阅读 0

文件操作

推荐一款超级好用的面试题复习工具:牛客网,涵盖了各个领域的面试题库,还有各大厂商的真题!

有各种语言的编程题,很多公司都用这个网站参加笔试。 快来研究问题吧! ! !

1. 文件的使用

之前的通讯录,如果每次运行完之后再次启动,就会发现上次的数据全部消失了,每次都要重新输入。 使用文件,我们可以将数据直接存储在计算机的硬盘上,实现数据的持久化。

2. 打开和关闭文件 2.1 文件指针

每个使用过的文件都会在内存中开辟一个对应的文件信息区域,用于存储文件相关信息(如文件名、文件状态和文件当前位置等)。 该信息存储在结构变量中。 结构体类型由系统声明并命名为FILE。 当我们打开文件时,系统会自己创建结构体变量。 我们可以使用FILE指针来维护结构体变量。

2.2 打开和关闭文件

在读取或写入之前应打开文件,在使用后应关闭文件。

这有点像动态内存中的内存泄漏问题。 您不能只打开文件而不关闭它。

//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream );

2.3 文件的打开方式及顺序读写

打开方法:

“r”(只读)打开一个文本文件以供输入

“w”(只写)打开一个文本文件进行输出

“a”(追加)将数据添加到文件末尾

“rb”(只读)打开一个二进制文件用于输入

“wb”(只写)打开二进制文件进行输出

“r+”(读写)打开文本文件进行读写

“w+”(读写)创建一个新的文本文件用于读写

“a+”(读写)打开文本文件进行读写

“rb+”(读写)打开二进制文件进行读写

“wb+”(读写)创建一个新的二进制文件用于读写

“ab+”(读写)打开二进制文件进行读写

文件顺序读写:

我们在目录下创建文本文档text.txt来验证:

2.3.1 fputc

int fputc( int c, FILE *stream );

写一个字符

int c 表示的公式的 ASCII 值。

int main()
{
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	char i = 'a';
	for (i = 'a'; i < 'z'; i++)
	{
		fputc(i, pf);
	}
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行后查看txt文档:

2.3.2 fgetc

int fgetc( FILE *stream );

读一个字符。

int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	int ch;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

2.3.3 输出量

int fputs( const char *string, FILE *stream );

写一行字符。

int main()
{
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fputs("hello", pf);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

有些人可能会有疑问,前面写的代码去了哪里:

当我们使用“w”时,它会自动清除然后写入。

如果使用“a”,则附加它:

FILE* pf = fopen("text.txt", "a");

2.3.4 fgets

char *fgets( char *string, int n, FILE *stream );

读取成功时返回,失败或到达文件末尾时返回NULL。

读取一行数据。

int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	char arr[20];
	fgets(arr, 5, pf);
	printf(arr);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

可以看到这里只读取了四个字符。 原来这里的5包含'\0'。

2.3.5

int fprintf( FILE *stream, const char *format [, argument ]...);

格式化并写入(文件)数据。

struct A
{
	char a[10];
	int b;
};
int main()
{
	struct A a = { "abcdef", 20 };
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fprintf(pf, "%s %d", a.a, a.b);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行后结果:

2.3.6

int fscanf( FILE *stream, const char *format [, argument ]... );

格式化读取(文件)数据。

struct A
{
	char a[10];
	int b;
};
int main()
{
	struct A a = { 0 };
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fscanf(pf, "%s %d", a.a, &a.b);
	printf("%s %d", a.a, a.b);
	//fprintf(stdout, "%s %d", a.a, a.b);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行后结果:

2.3.7

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

以二进制形式编写(必须是文件)。

因为你想将二进制写入文件,所以它是“wb”。

struct A
{
	char a[10];
	int b;
};
int main()
{
	struct A a = { "abcdef", 20 };
	FILE* pf = fopen("text.txt", "wb");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//以二进制写
	fwrite(&a, sizeof(struct A), 1, pf);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行后结果:

有一些二进制代码我们看不懂,但是我们可以用函数把它们读出来:

2.3.8 恐惧

size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

读取二进制文件(必须是文件)。

struct A
{
	char a[10];
	int b;
};
int main()
{
	struct A a = { "abcdef", 20 };
	FILE* pf = fopen("text.txt", "rb");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//以二进制读
	fread(&a, sizeof(struct A), 1, pf);
	printf("%s %d", a.a, a.b);
	//关闭
	fclose(pf);
	pf = NULL;
	return 0;
}

运行后结果:

2.4 比较一组函数

扫描//

//

scanf是标准输入的格式化输入语句

是标准输出的格式化输出语句

是所有标准输入流的格式化输入语句

是所有标准输出流的格式化输出语句

:

将格式化数据转换为字符串。

:

从字符串转换为格式化数据。

struct A
{
	char a[10];
	int b;
};
int main()
{
	struct A a = { "abcdef", 20 };
	struct A tmp = { 0 };
	char buf[100] = {0};
	//把s中的格式化数据转化成字符串放入buf中
	sprintf(buf, "%s %d", a.a, a.b);
	//从字符串buf中获取格式化数据到tmp中
	sscanf(buf, "%s %d", tmp.a, &tmp.b);
	return 0;
}

3.随机读写 3.1 fseek

根据文件指针的位置和偏移量定位文件指针。

int fseek( FILE *stream, long offset, int origin );

当我们文件中的内容为:“”时,用fgetc()读取时,如果要读取f,只能从a开始往后读取。 这时候就可以使用fseek来解决这个问题。

fseek 的三个起始位置:

文件开头

标签: 格式化 字符 指针

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码