当前位置: 首页 > article >正文

文件(下)

目录

1。顺序读写函数

1.1 fputs

1.2fgets

 1.3fprintf

1,4fscanf

1.5 sprintf

1.6 sscanf 

 1.7 fwrite

1.8 fread

2 ⽂件的随机读写

2.1 fseek

2.2 ftell

2.3 rewind

3 . ⽂件读取结束的判定

3.1 被错误使⽤的 feof

拷贝文件

 ferror 

4.⽂件缓冲区


书接下文上次我讲到

1。顺序读写函数

1.1 fputs

#include <stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");

	}
	//写文件
	fputs("are you ok?", pf);//fputs是输入字符串

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

当你运行完后依照昨天的步骤找到要写入的文件打开出查看

记事本中实现了。

1.2fgets

#incldue <stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");

	}
	//读文件
	char ch[20] = "xxxxxxxxxx";
	fgets(ch,5, pf);
	printf("%s", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 1.3fprintf

在先了fprint 的时候我们来了解一些它与printf的区别。

 

 我们发现fprintf和printf只相差一个流 ,下面用代码来解释

#include <stdio.h>
int main()
{
	char book[40] = "wedadf";
	char name[20] = "ch ";
	float price = 999.9f;
	//打开文件
	FILE* pf = fopen("text.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");

	}
	//写文件
	fprintf(pf, "%s %s %.1f", book, name, price);//与printf的格式相仿,只是多加了流 
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

1,4fscanf

 

 我们可以发现这个与上面的printf 和fprintf 相似,

#include <stdio.h>
int main()
{
	char book[40] = "wedadf";
	char name[20] = "ch ";
	float price = 999.9f;
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");

	}
	//读 文件
	fscanf(pf, "%s %s %f", book, name, &price);//将记事本的内容写到了数组中
	printf(" % s % s % f", book, name, price);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 

1.5 sprintf

#include <stdio.h>
struct  S
{
	char name[20];
	int age;
	float score;

};
int main()
{
	char arr[100] = { 0 };
	struct S s = { "chnegyun",23,50.4f };
//将s中的数据转换成字符串,存放在arr中
	sprintf(arr, "%s %d %.1f",s.name,s.age,s.score );//把结构体的成员放到arr中
	printf("%s \n", arr);
	return 0;

结构体的内容放到了arr中

1.6 sscanf 

#include <stdio.h>
struct  S
{
	char name[20];
	int age;
	float score;

};
int main()
{
	char arr[100] = { 0 };
	struct S s = { "chnegyun",23,50.4f };
	//将s中的数据转换成字符串,存放在arr中
	sprintf(arr, "%s %d %.1f",s.name,s.age,s.score );//把结构体的成员放到arr中
	//从arr中提取格式化数据,放在tmp中
	sscanf(arr, "%s %d %f", s.name, &(s.age), &(s.score));
	printf("%s %d %f ", s.name, s.age, s.score);
	return 0;
}

 打印结果

 1.7 fwrite

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

 

当我们查看的时候就会出现错误的编码,因为这是二进制形式写到文件中

 这个时候我们就得讲下个函数了fread 

1.8 fread

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

 可以发现fwrite 和fread 的参数是相同的。

#include <stdio.h>
struct S
{
	char name[20];
	int age;
	float score;

};
int main()
//读取二进制信息写到文件中
{
	//打开文件
	struct S s = { "chenyun ",23,3.14 };
	FILE* pf = fopen("text.txt","rb");
	if (pf == NULL)
	{
		perror("fopen ");
		return 1;
	}

	//写文件
	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %f",s.name,s.age,s.score );

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

 我们发现这个代码真的打印出来的

2 ⽂件的随机读写

2.1 fseek

根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)

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

#incldue <stdio.h>
int main()
{
	//读取二进制信息写到文件中
	//打开文件

	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen ");
		return 1;
	}
	//读文件
	int  ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//fseek(pf, 4, SEEK_SET);
	//ch = fgetc(pf);
	//printf("%c\n", ch);


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

 

 前两个就打印出来了,

2.2 ftell

返回⽂件指针相对于起始位置的偏移量

long int ftell ( FILE * stream );

#include <stdio.h
int main()
{	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen ");
		return 1;
	}
	//读文件
	int  ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	fseek(pf, -1, SEEK_END);
	ch = fgetc(pf);
	printf("%c\n", ch);
	printf("%d", ftell(pf));//文件有多少数字就会返回几

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

 记事本中存放了5个字符,那么我们打印看一看结果。

 

 如果我在记事本中增加字母,那么打印出来的数字也会随着增加。下面我们来实现一下。

 

 这里就会增加。

2.3 rewind

让⽂件指针的位置回到⽂件的起始位置

回到了起始位 

#include  <stdio.h>
int main()
{	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen ");
		return 1;
	}
	//读文件
	int  ch = 0;
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	fseek(pf, -1, SEEK_END);
	ch = fgetc(pf);
	printf("%c\n", ch);
	printf("%d\n", ftell(pf));//文件有多少数字就会返回几
	rewind(pf);// 重新想文件的位置回到起始位置 a 
	ch = fgetc(pf);
	printf("%c\n", ch);
	//关文件
	fclose(pf);
	pf = NULL;
	return 0;
}

3 . ⽂件读取结束的判定

3.1 被错误使⽤的 feof

牢记:在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。 feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束

1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets)、fgetc 判断是否为 EOF .

• fgets 判断返回值是否为 NULL .

2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数。

• fread判断返回值是否⼩于实际要读的个数。

拷贝文件

将text 1 拷贝到text2 中

下面请看代码:

#include <stdio.h>
int   main()
{
	//打开文件
	FILE* pfread = fopen("text1.txt", "r");
	if (pfread == NULL)
	{
		perror("fopen");
		return 1;
	}
	 
	FILE* pfwrite = fopen("text2.txt", "w");//如果没有该文件 w 会自动创建一个
	if (pfwrite == NULL)
	{
		perror("fopen ");
		fclose(pfread);
		return 1;
	}
	//读/写文件
	int  c = 0;
	while ((c=fgetc(pfread)) != EOF)
	{
		fputc(c,pfwrite);
	}
	//关闭文件
	fclose(pfread);
	pfread = NULL;
	fclose(pfwrite);
	pfwrite =NULL;


	return 0;
}

有了前面的理解,相信大家看这个这些代码应该都不陌生了。 

#include <stdio.h>
int   main()
{
	//打开文件
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	

	//读/写文件
	int  c = 0;
	while ((c = fgetc(pf)) != EOF)
	{
		printf("%c ", c);
	}
	int ret = feof(pf);
	printf("%d \n", ret);
	ret = ferror (pf);
	printf("%d \n", ret);


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

	return 0;
}
 ferror 

ferror 要这样使用

4.⽂件缓冲区

ANSIC 标准采⽤“缓冲⽂件系统” 处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为 程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输 ⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓 冲区的⼤⼩根据C编译系统决定的。

 大家有兴趣的可以研究一下这个代码

 #include <stdio.h>
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{
    FILE* pf = fopen("test.txt", "w");
    fputs("abcdef", pf);//先将代码放在输出缓冲区
    printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");
    Sleep(10000);
    printf("刷新缓冲区\n");
    fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)
    //注:fflush 在⾼版本的VS上不能使⽤了
    printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
    Sleep(10000);
    fclose(pf);
    //注:fclose在关闭⽂件的时候,也会刷新缓冲区
    pf = NULL;
    return 0;
}

 到这里文件就结束了。我们的c语言也接近尾声了,


http://www.kler.cn/news/361400.html

相关文章:

  • leetcode day3 1+14+15
  • 基于SpringBoot+Vue+uniapp微信小程序的澡堂预订的微信小程序的详细设计和实现
  • 鸿蒙开发:实现一个超简单的网格拖拽
  • MySQL~数据类型
  • springboot 项目集成spring security(极简版)
  • Vue.js 从入门到精通:全面解析组件化、路由与状态管理(附 Todo 案例)
  • 2024.10.22 软考学习笔记
  • 阅读笔记 Marketing Management Chapter 12
  • 筑牢理性防线,“卡游启智,理性护航”青少年健康消费倡议发布
  • java工程启动优化
  • Redis持久化机制
  • 深入理解InnoDB底层原理:从数据结构到逻辑架构
  • STM32烧写准备
  • 什么是感知与计算融合?
  • 在元学习中,**1-shot**、**5-shot**、和**10-shot**等术语常用于描述少样本学习中的训练条件。这些术语的具体含义是:
  • Python 函数详解
  • CLion远程开发Ubuntu,并显示helloworld文字框
  • 深度学习(二)框架与工具:开启智能未来之门(2/10)
  • 【计网笔记】物理层
  • 每天坚持学英语,多久能说流利呢?
  • 闯关leetcode——190. Reverse Bits
  • Github 2024-10-20 php开源项目日报Top10
  • 解锁文本数据可视化的无限可能:Wordcloud库全解析
  • 微服务接口测试的通用注意点
  • 【C++】string类(2)
  • Construmart借力SNP全面升级SAP S/4HANA和 SAP CAR 改进零售业务流程