C语言文件操作

144 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情


1. 为什么使用文件

为了使数据更长久的储存。

2. 什么是文件

文件包括程序文件和数据文件 程序文件:源文件,目标文件,可执行文件 数据文件:程序运行过程中可以进行读写的文件。 文件名包括3部分:文件路径,文件名和文件后缀。

3. 文件的打开和关闭

文件指针

每个文件在打开的时候,都会开辟一个文件信息区。这个文件信息区的类型为FILE类型,对于读写都是通过FILE指针来实现的。

文件的打开和关闭

需要的头文件为stdio.h,文件打开后,等到不使用它的时候,不要忘记关闭文件。

fopen

在这里插入图片描述

第一个参数为文件系统名,第二个参数为文件访问的模式 访问模式如下: 在这里插入图片描述 返回类型为FILE*。文件访问成功返回指向新文件流的指针。失败返回空指针。

fclose

在这里插入图片描述

关闭文件,参数为FILE*类型的流。返回类型为int 有没有发现这个函数和free相似。

简单的使用一下

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fclose(p);
	p = NULL;
	return 0;
}
int main()
{
	FILE* p = fopen("test.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fclose(p);
	p = NULL;
	return 0;
}

4. 文件的顺序读写

在这里插入图片描述

fgetc

在这里插入图片描述

参数为FILE*的流,成功时为作为 unsigned char 获得并转换为 int 的字符,失败时为EOF

例:

int main()
{
	FILE* p = fopen("test.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	int ch;
	while ((ch=fgetc(p))!=EOF)
	{
		printf("%c", ch);
	}
	fclose(p);
	p = NULL;
	return 0;
}

fputc

在这里插入图片描述

写入字符 ch 到给定输出流stream 成功时,返回被写入字符。失败时,返回EOF

例:

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	char ch;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		fputc(ch, p);
	}
	fclose(p);
	p = NULL;
	return 0;
}

fgets

在这里插入图片描述

stream流中最多获得n-1个字符到string中。遇到换行符\n或者是文件结束时停止分析。并返回srting。若没有读取字符,返回空指针,不覆盖string指向字符串的内容。

例:

int main()
{
	FILE* p = fopen("test.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	char arr[200]={0};
	while (fgets(arr, 200, p))
	{
		printf("%s", arr);
	}
	fclose(p);
	p = NULL;
	return 0;
}

fputs

在这里插入图片描述

把字符串写入stream中 成功时,返回非负值。失败时,返回 EOF

例:

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fputs("acd", p);
	fclose(p);
	p = NULL;
	return 0;
}

fscanf

在这里插入图片描述

从文件流 stream 读取数据。 返回值和scanf的返回方式一样。

例:

int main()
{
	FILE* p = fopen("test.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	char arr[200] = { 0 };
	fscanf(p,"%s",arr);
	printf("%s\n", arr);
	fclose(p);
	p = NULL;
	return 0;
}

fprintf

在这里插入图片描述

写结果到文件流 stream 用法和printf的用法非常相似。

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fprintf(p, "%s", "哈哈哈");
	fclose(p);
	p = NULL;
	return 0;
}

fread

在这里插入图片描述

把流中的数据读入到数组中 size为每个对象字节的大小 count要读取的对象的个数。

例:

int main()
{
	FILE* p = fopen("test.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	char arr[200]={0};
	fread(arr, 1, 100, p);
	printf("%s\n", arr);
	fclose(p);
	p = NULL;
	return 0;
}

fwrite

在这里插入图片描述

buffer指向里面的数据写到stream流中 size是一个对象的大小,count为对象的个数

例:

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	char arr[200] = "abcdefds";
	fwrite(arr, 1, 20, p);
	fclose(p);
	p = NULL;
	return 0;
}

sscanf

格式化读入 从buffer中的数据读入到后面的格式化中 在这里插入图片描述 例:

struct s
{
	int age;
	char name[30];
};
int main()
{
	struct s a;
	char arr[100]="20zhangsan";
	sscanf(arr, "%d %s", &(a.age), a.name);
	return 0;
}

sprintf

格式化写入 把格式化的数据写入到字符串中 在这里插入图片描述 例:

struct s
{
	int age;
	char name[30];
};
int main()
{
	struct s a={20,"zhangsan"};
	char arr[100] = { 0 };
	sprintf(arr, "%d %s", a.age, a.name);
	return 0;
}

5. 文件的随机读写

fseek

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

设置文件流 stream 的文件位置指示器的指向 关于返回值,成功返回0,否则返回非零。

例:

int main()
{
	FILE* p = fopen("test.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fputs("sscbcsd", p);
	fseek(p, 2, SEEK_SET);
	fputs("哈哈", p);
	fclose(p);
	p = NULL;
	return 0;
}

ftell

在这里插入图片描述 例:

int main()
{
	FILE* p = fopen("test.txt", "wb");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fseek(p, 2, SEEK_SET);
	long ret=ftell(p);
	printf("%d\n", ret);
	fclose(p);
	p = NULL;
	return 0;
}

rewind

在这里插入图片描述 例:

int main()
{
	FILE* p = fopen("test.txt", "wb");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fseek(p, 2, SEEK_SET);
	
	rewind(p);
	printf("%ld\n", ftell(p));
	fclose(p);
	p = NULL;
	return 0;
}

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

数据在内存中是怎么储存,在文件中就是怎么储存,这就是二进制文件。 把内存的数据转换成ASCII形式存储,这种就是文本文件。

7. 文件读取结束的判定

下面两个函数分别判断文件是以那种方式结束的,是错误原因导致的还是文件读完结束的。

ferror

若文件流已出现错误则为非零值,否则为 ​0​ 在这里插入图片描述

feof

若已抵达流尾则为非零值,否则为 ​0​ 在这里插入图片描述 例:

int main()
{
	FILE* p = fopen("test.txt", "wb");
	if (p == NULL)
	{
		perror("fopen");
		return 0;
	}
	fseek(p, 2, SEEK_SET);
	rewind(p);
	printf("%ld\n", ftell(p));
	if (feof(p))
		printf("文件没有读取完\n");
	else if (ferror(p))
		printf("文件读取错误\n");
	fclose(p);
	p = NULL;
	return 0;
}

8. 文件缓冲区

无论是读还是写,都是从缓冲区中拿。