79.【C语言】文件操作(4)

时间:2024-10-14 08:05:49

目录

1.剩余4个顺序读写函数

1.fprintf函数

代码示例

2.fscanf函数

代码示例

3.对比(printf,scanf),(fprintf,fscanf)和(spirntf,sscanf)这三组函数

sprintf代码示例

​编辑

sscanf代码示例

问题:为什么没有打印"1 0.990000 Hello World!"?

4.fread函数

代码示例

1.知道存储的元素个数

其他写法

2.不知道存储的元素个数

5.fwrite函数

代码示例


1.剩余4个顺序读写函数

1.fprintf函数

声明:int fprintf ( FILE * stream, const char * format, ... );

格式:fprintf(文件指针, "以何种类型打印数据",变量 );

作用:向流中写入格式化的数据

对比printf函数的声明:int printf ( const char * format, ... );

其实只是多了一个FILE * stream

相当于在printf函数的括号内的最前面添加文件指针

代码示例

#include <stdio.h>
int main()
{
	int a = 1;
	double b = 0.99;
	char arr[20] = {"Hello World!"};
	FILE* p = fopen("abc.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	fprintf(p, "%d %lf %s", a, b, arr);
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}

执行后打开abc.txt

2.fscanf函数

声明:int fscanf ( FILE * stream, const char * format, ... );

格式:fscanf(文件指针, "以何种类型输入数据",变量);

作用:从流中读取格式化的数据

对比scanf函数的声明:int scanf ( const char * format, ... );

其实只是多了一个FILE * stream

相当于在scanf函数的括号内的最前面添加文件指针

代码示例

确保abc.txt录入了以下内容

1 0.990000 Hello World!

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a;
	double b;
	char arr[20] = { 0 };
	FILE* p = fopen("abc.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	fscanf(p, "%d %lf %s", &a, &b, &arr);
	printf("%d %lf %s", a, b, arr);
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}

 

实际上,fprintf支持所有的输出流,fscanf支持所有的输入流

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a;
	double b;
	char arr[20] = { 0 };
	FILE* p = fopen("abc.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	fscanf(stdin, "%d %lf %s", &a, &b, &arr);
	fprintf(stdout,"%d %lf %s", a, b, arr);
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}

3.对比(printf,scanf),(fprintf,fscanf)和(spirntf,sscanf)这三组函数

有关printf,scanf函数的讲解见下方链接

31.【C语言】详解printf

7.5【C语言】补充printf细节

32.【C语言】详解scanf

printf:针对标准输出流(stdout),将数据以格式化的形式输出到屏幕上

scanf:针对标准输入流(stdin),从键盘上输入格式化的数据

fprintf:针对所有的输入流,格式的输入函数

fscanf:针对所有的输出流,格式的输出函数

sprintf:向字符串中写入格式化的数据-->将格式化的数据转换成字符串(多和一,即整合到一个字符串中)

sprintf代码示例

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a = 1;
	double b = 0.99;
	char arr[20] = { "Hello World!" };
	char str[100] = { 0 };
	sprintf(str, "%d %lf %s", a, b, arr);
	printf("%s", str);
	return 0;
}

 

将a,b,arr中的数据均以字符串的形式打印

sscanf:从字符串中提取格式化的数据

sscanf代码示例

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int a = 1;
	double b = 0.99;
	char arr[20] = { "Hello World!" };
	char str[100] = { 0 };
	//将格式化的数据转换成字符串
	sprintf(str, "%d %lf %s", a, b, arr);
	int _a = 0;
	double _b = 0;
	char _arr[30] = { 0 };
	//从字符串中读取格式化的数据
	sscanf(str, "%d %lf %s", &_a, &_b, &_arr);
	printf("%d %lf %s", _a, _b, _arr);
	return 0;
}

问题:为什么没有打印"1 0.990000 Hello World!"?

在文章说过,sscanf以%s从从字符串中提取格式化的数据时,和scanf的特性相同,从当前第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止

显然Hello World!的两个单词之间有空格,因此只打印前一个单词

4.fread函数

声明:size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

格式:fwrite(ptr(指向要读的数据), 每个元素的大小(单位字节), 读取元素的个数, 的流);

作用:从流中读取数据块(二进制输入,则在fopen函数的mode参数要写为rb)

代码示例

1.知道存储的元素个数
#include <stdio.h>
int main()
{
	int arr[5] = { 0 };
	FILE* p = fopen("abc.txt", "rb");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	fread(arr, sizeof(arr[0]), 5, p);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}

 

其他写法

上方代码一次性读取了5个元素,其实也可以一次读取1个元素,循换5次

#include <stdio.h>
int main()
{
	int arr[5] = { 0 };
	FILE* p = fopen("abc.txt", "rb");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	for (int i = 0; i < 5; i++)
	{
		fread(arr, sizeof(arr[0]), 1, p);
	}
	for (int j = 0; j < 5; j++)
	{
		printf("%d ", arr[j]);
	}
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}
2.不知道存储的元素个数

要从fread函数的返回值看,返回值为0代表读取失败,显然可以设计一个while循环

	int i = 0;
	while (fread(arr+i, sizeof(arr[0]), 1, p))
	{
		printf("%d ", arr[i]);
		i++;
	}

5.fwrite函数

声明:size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

格式:fwrite(ptr(指向要写的数据), 每个元素的大小(单位字节), 写入元素的个数, 写入的流);

作用:向流中写入数据块(二进制输出,则在fopen函数的mode参数要写为wb)

其实在74.【C语言】文件操作(1)文章中提到了一点内容

代码示例

#include <stdio.h>
int main()
{
	int arr[] = {1,2,3,4,5};
	FILE* p = fopen("abc.txt", "wb");
	if (p == NULL)
	{
		perror("fopen");
		return 1;//错误返回
	}
	fwrite(arr, sizeof(arr), 5, p);
	fclose(p);
	p = NULL;//将野指针置空
	return 0;
}

 默认情况下,打开abc.txt是乱码

使用二进制编辑器打开

VS默认以小端序存储数据