C++(week3):C语言文件操作

文章目录

    • (十二) 文件
      • 1.流
        • (1)流模型
        • (2)程序员视角的文件
        • (3)缓冲区类型
        • (4)标准流
        • (5)二进制文件 与 文本文件
        • (6)文件流的接口(API)
      • 2.打开/关闭文件
        • (1)fopen
        • (2)fclose
        • (3)示例代码
      • 3.读/写文件
        • (1)fgetc / fputc:一个字符一个字符地读写
        • (2)fgets / fputs:一行一行地读写
          • ①fgets
          • ②fputs
          • ③代码
        • (3)fscanf / fprintf:格式化地读写
          • ①fscanf
          • ②fprintf
          • ③代码
        • (4)fread / fwrite:读写二进制文件
          • ①fread
          • ②fwrite
          • ③代码
      • 4.文件定位、移动文件位置
        • (1)fseek
        • (2)ftell
        • (3)rewind
        • (4)课堂小练习
      • 5.错误处理:perror

(十二) 文件

1.流

在这里插入图片描述


(1)流模型

data sink:数据接收端、数据汇

在这里插入图片描述

优点:
①程序员读写文件时,不需要关心文件的位置
②数据源(data source) 和 数据汇(data sink) 是解耦的


(2)程序员视角的文件

存放的是一个一个字节。
EOF(end of file)指向文件末尾后一个位置,EOF是一个宏,值为-1

在这里插入图片描述


(3)缓冲区类型

①满缓冲:缓冲区空才从输入流读数据;缓冲区满向输出流中写入数据。
②行缓冲:以行为单位进行读和写
③无缓冲:没有缓冲区,立即输入输出,例如:标准错误流 stderr

在这里插入图片描述

在这里插入图片描述

刷新输出缓冲区 (fflush),将输出缓冲区的内容输出到屏幕上


(4)标准流

①stdin:标准输入
②stdout:标准输出
③stderr:标准错误

这三个标准流,不需要程序员手动声明、创建、关闭

在这里插入图片描述


(5)二进制文件 与 文本文件

1.区别
(1)二进制文件:byte。(二进制文件以字节为单位,人类不可读,但体积小)

(2)文本文件:字符 + 编码。(文本文件以字符为单位,一个字符占几个字节)

在这里插入图片描述


2.优缺点:
文本文件:人类可读,数据量大
二进制文件:人类不可读,数据量小

在这里插入图片描述


(6)文件流的接口(API)

1.打开文件流 :fopen

2.读/写文件:
统计、转换、加密解密

2.5 移动文件位置

3.关闭文件流:fclose



2.打开/关闭文件

(1)fopen

1.fopen的参数
①filename是文件的路径
②mode是打开模式

FILE* fopen(const char* filename, const char* mode);

在这里插入图片描述


2.文件路径
(1)绝对路径
从根目录 (或者盘符) 开始,一直到文件所在的位置,比如:“c:/project/test.dat”。
(2)相对路径
另一种是相对路径:从当前工作目录开始,一直到文件所在的位置,比如:“in.dat”。

相对路径用的多,因为一个app各文件的相对路径一般不变,但是绝对路径,当安装到不同电脑上时一般不同。


3.打开模式(mode):文件的类型、对文件的操作(r,w)
(1)以文本文件方式打开
①“r”,读(read):要求文件存在。若不存在则返回NULL
②“w”,写(write):若文件存在,清空文件内容;若文件不存在,创建文件。
③“a”,追加(append):若文件存在,不修改原内容,每次都在文件末尾追加写入;若文件不存在,创建文件。

文件存在文件不存在
r只读返回NULL
w清空文件内容创建文件
a追加创建文件

在这里插入图片描述

在这里插入图片描述


(2)以二进制文件打开

在这里插入图片描述


(2)fclose

fclose 可以关闭程序不再使用的文件。

int fclose(FILE* stream);

如果成功关闭, fclose 返回零;否则返回 EOF


(3)示例代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	//1.打开文件
	FILE* stream = fopen("a.txt", "w");
	if (stream == NULL) {
		fprintf(stderr, "file open failed.\n");
		exit(1);
	}

	//2.读写文件 (统计,转换,加密,解密)


	//3.关闭文件
	fclose(stream);

	return 0;
}



3.读/写文件

在这里插入图片描述

(1)fgetc / fputc:一个字符一个字符地读写

1.函数参数

int fgetc(FILE* stream);
int fputc(int c, FILE* stream);

2.惯用法:一个字符一个字符地读取,直到文件末尾

int c;
while((c = fgetc(src)) != EOF){
	//操作
}

3.完整代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>

int main(int argc, char* argv[]) {
	//xxx.exe src dst
	//0.参数校验
	if (argc != 3) {
		fprintf(stderr, "Usage: %s src dst\n", argv[0]);
		exit(1);
	}
	//1.打开文件
	FILE* src = fopen(argv[1], "r");
	if (!src) {
		fprintf(stderr, "Open %s failed.\n", argv[1]);
		exit(1);
	}

	FILE* dst = fopen(argv[2], "w");
	if (!dst) {
		fprintf(stderr, "Open %s failed.\n", argv[2]);
		fclose(src);
		exit(1);
	}

	//2.读写文件 (统计,转换,加密,解密)
	//(1)一个字符一个字符地读写:fgetc, fputc
	//把大写字母转换为小写字母
	int c;
	while ((c = fgetc(src)) != EOF) {
		fputc(tolower(c), dst);
	}

	printf("大写字母已全部转换为小写字母\n");

	//3.关闭文件
	fclose(src);
	fclose(dst);

	return 0;
}

(2)fgets / fputs:一行一行地读写
①fgets

1.函数参数

char* fgets(char* str, int count, FILE* stream);

参数:
①str:指向第一个字符数组
②count:能够写入的最大字符数量 (通常是str指向字符数组的长度)
③stream:输入流
④返回值:成功返回str,失败返回NULL

2.fgets的特点
①fgets会读\n
②gets(str) 等价于 fgets(str, ∞, stdin) ,即gets不会检查数组越界


②fputs

1.函数参数

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

参数:
①str:要写的字符串(以’\0’结尾的字符串)
②stream:输出流
③返回值:成功返回一个非负值;失败返回EOF,并设置errno


2.fputs的特点
①fputs原样输出字符串,puts在字符串后多输出一个换行符’\n’
②puts(str) 等价于 fputs(str, stdout)

在这里插入图片描述


③代码

1.核心代码:

#define MAXLINE 128
//2.读写文件:
//(2)一行一行地读写
//每行加序号
char line[MAXLINE];
char buffer[MAXLINE];
//fgets(line, MAXLINE, src);
//fgets(line, MAXLINE, src);
int line_num = 1;
while ((fgets(buffer, MAXLINE, src)) != NULL) {
	sprintf(line, "%d.%s", line_num, buffer);
	fputs(line, dst);
	line_num++;
}

2.完整代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>
#define MAXLINE 128

int main(int argc, char* argv[]) {
	//xxx.exe src dst
	//0.参数校验
	if (argc != 3) {
		fprintf(stderr, "Usage: %s src dst\n", argv[0]);
		exit(1);
	}
	//1.打开文件
	FILE* src = fopen(argv[1], "r");
	if (!src) {
		fprintf(stderr, "Open %s failed.\n", argv[1]);
		exit(1);
	}

	FILE* dst = fopen(argv[2], "w");
	if (!dst) {
		fprintf(stderr, "Open %s failed.\n", argv[2]);
		fclose(src);
		exit(1);
	}

	//2.读写文件:
	//(2)一行一行地读写
	//每行加序号
	char line[MAXLINE];
	char buffer[MAXLINE];
	//fgets(line, MAXLINE, src);
	//fgets(line, MAXLINE, src);
	int line_num = 1;
	while ((fgets(buffer, MAXLINE, src)) != NULL) {
		sprintf(line, "%d.%s", line_num, buffer);
		fputs(line, dst);
		line_num++;
	}
	printf("每行内容前面已加上序号。\n");

	//3.关闭文件
	fclose(src);
	fclose(dst);

	return 0;
}

(3)fscanf / fprintf:格式化地读写
①fscanf
int fscanf(FILE* stream, const char* format, ...);

在这里插入图片描述


②fprintf
int fprintf(FILE* stream, const char* format, ...);

在这里插入图片描述


③代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>
#define MAXLINE 128

typedef struct Student {
	int id;
	char name[25];
	char gender;
	int chinese;
	int math;
	int english;
} Student;

int main(int argc, char* argv[]) {
	//xxx.exe src dst
	//0.参数校验
	if (argc != 3) {
		fprintf(stderr, "Usage: %s src dst\n", argv[0]);
		exit(1);
	}
	//1.打开文件
	FILE* src = fopen(argv[1], "r");
	if (!src) {
		fprintf(stderr, "Open %s failed.\n", argv[1]);
		exit(1);
	}

	FILE* dst = fopen(argv[2], "w");
	if (!dst) {
		fprintf(stderr, "Open %s failed.\n", argv[2]);
		fclose(src);
		exit(1);
	}

	//2.读写文件 (统计,转换,加密,解密)
	//(3)格式化地读写
	Student students[5];
	for (int i = 0; i < 5; i++) {
		fscanf(src, "%d%s %c%d%d%d",
			&students[i].id,
			students[i].name,
			&students[i].gender,
			&students[i].chinese,
			&students[i].math,
			&students[i].english);
	}

	//修改成绩
	for (int i = 0; i < 5; i++) {
		students[i].chinese *= 10;
		students[i].math *= 10;
		students[i].english *= 10;
	}

	for (int i = 0; i < 5; i++) {
		fprintf(dst, "%d %s %c %d %d %d\n",
			students[i].id,
			students[i].name,
			students[i].gender,
			students[i].chinese,
			students[i].math,
			students[i].english);
	}

	printf("成绩已修改。\n");

	//3.关闭文件
	fclose(src);
	fclose(dst);

	return 0;
}
//a.txt
1 Edward M 100 100 100
2 Amber  F  99  99  99
3 Sam    M  98  98  98 
4 Windy  F  97  97  97
5 Chole  F  96  96  96

(4)fread / fwrite:读写二进制文件
①fread

在这里插入图片描述


②fwrite

在这里插入图片描述


③代码

1.核心代码:

//读写二进制文件 (复制)
char buffer[BUFSIZE];
int bytes;
while ((bytes = fread(buffer, 1, BUFSIZE, src)) > 0) {
	fwrite(buffer, 1, BUFSIZE, dst);
}

2.完整代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define BUFSIZE 4096

int main(int argc, char* argv[]) {
	//xxx.exe src
	//0.参数校验
	if (argc != 3) {
		fprintf(stderr, "Usage: %s src dst\n", argv[0]);
		exit(1);
	}
	//1.打开文件
	FILE* src = fopen(argv[1], "rb");
	if (!src) {
		fprintf(stderr, "Open %s failed.\n", argv[1]);
		exit(1);
	}

	FILE* dst = fopen(argv[2], "wb");
	if (!dst) {
		fprintf(stderr, "Open %s failed.\n", argv[2]);
		fclose(src);
		exit(1);
	}

	//2.读写文件 
	//(4)读写二进制文件 (复制)
	char buffer[BUFSIZE];
	int bytes;
	while ((bytes = fread(buffer, 1, BUFSIZE, src)) > 0) {
		fwrite(buffer, 1, BUFSIZE, dst);
	}


	//3.关闭文件
	fclose(src);
	fclose(dst);

	return 0;
}



4.文件定位、移动文件位置

(1)fseek
int fseek(FILE* stream, long int offset, int whence);

whence的三个宏:
SEEK_SET:文件的起始位置,0
SEEK_CUR:文件的当前位置,pos
SEEK_END:文件的末尾位置,EOF

在这里插入图片描述

在这里插入图片描述


(2)ftell
long int ftell(FILE* stream);

在这里插入图片描述


(3)rewind
void rewind(FILE* stream);

在这里插入图片描述


(4)课堂小练习

在这里插入图片描述

难点:
①如何确定文件的大小

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

char* readFile(const char* path) {
	//1.打开文件
	FILE* stream = fopen(path, "rb");
	if (stream == NULL) {  //!stream
		fprintf(stderr, "Open %s failed\n", path);
		exit(1);
	}

	//2.确定文件大小
	fseek(stream, 0, SEEK_END);
	long n = ftell(stream);
	char* content = malloc((n + 1) * sizeof(char));  // 1 for '\0'

	//3.读取文件
	rewind(stream);  //回到文件开头
	int bytes = fread(content, 1, n, stream);
	content[bytes] = '\0';

	//4.关闭文件
	fclose(stream);

	return content;
}

int main(int argc, char* argv[]) {
	//0.参数校验
	if (argc != 2) {
		fprintf(stderr, "Usage: %s filename\n", argv[0]);
		exit(1);
	}

	char* content = readFile(argv[1]);

	//操作
	printf("%s\n", content);

	free(content);

	return 0;
}



5.错误处理:perror

1.如何检测错误
2.如何打印错误信息

①返回值
errno,定义在 <errno.h> 头文件中
(每个线程都有自己的errno,线程特定变量)
strerror(errno),定义在 <string.h> 头文件中
perror,错误的前缀信息,后面自带了
相当于调用了fprintf(stderr,"%s: ",%s)


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(void) {
	printf("%d\n", errno);  // 0:没有错误

	FILE* fp = fopen("not_exist.txt", "r");
	printf("%d\n", errno); 

	printf("%s\n", strerror(errno));  //得到errno对应的错误信息,得到人类可读的字符串

	perror("prefix");  //错误的前缀信息

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/615060.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UIKit之UIButton

功能需求&#xff1a; 点击按钮切换按钮的文字和背景图片&#xff0c;同时点击上下左右可以移动图片位置&#xff0c;点击加或减可以放大或缩小图片。 分析&#xff1a; 实现一个UIView的子类即可&#xff0c;该子类包含多个按钮。 实现步骤&#xff1a; 使用OC语言&#xf…

【碳化硅】陷阱(traps)对SiC MOSFET阈值电压漂移的影响

这篇文章是关于硅碳化物(SiC)金属氧化物半导体场效应晶体管(MOSFET)的阈值电压漂移问题的研究。文章的主要目的是通过研究不同的陷阱(traps)对阈值电压漂移的影响,来解决SiC MOSFET的可靠性问题。 摘要(Abstract) 文章提出了一种研究方法,用于分析影响SiC MOSFET阈值…

YUV中Y颜色模型的采样

YUV的特点 相对于表示颜色的GUI&#xff0c; YUI将亮度&#xff08;用Y表示&#xff09;与色调&#xff08;用U和V表示&#xff09;分开来表示。又因为人类视网膜上的视网膜杆细胞要多于视网膜锥细 胞&#xff0c;说得通俗一些&#xff0c;视网膜杆细胞的作用就是识别亮度&…

【Delphi 爬虫库 6】使用正则表达式提取猫眼电影排行榜top100

正则表达式库的简单介绍 正则表达式易于使用&#xff0c;功能强大&#xff0c;可用于复杂的搜索和替换以及基于模板的文本检查。这对于输入形式的用户输入验证特别有用-验证电子邮件地址等。您还可以从网页或文档中提取电话号码&#xff0c;邮政编码等&#xff0c;在日志文件中…

Tiff文件解析和PackBits解压缩

实现了Tiff图片文件格式的解析&#xff0c;对Tiff文件中的PackBits压缩格式进行解压缩&#xff0c;对Tiff文件中每一个Frame转换成BufferedImage显示。 Java语言实现&#xff0c;Eclipse下开发&#xff0c;AWT显示图片。 public static TIFF Parse(final byte[] bytes) throw…

【Rollup】用rollup从0到1开发一个js插件并发布到npm

Rollup 是一个 JavaScript 模块打包器&#xff0c;专注于打包 ES6 模块将其编译回多种模块化格式&#xff0c;尤其适合打包库和框架&#xff0c;因为它可以生成更小、更高效的代码&#xff0c;并且特别适合将代码打包成可在浏览器中使用的库。 从0到1开发js插件 1.创建文件夹…

解决docker安装Wordpress速度过慢的问题

先可以在dockerhub上查看Wordpress的详情&#xff1a; Dockerhttps://hub.docker.com/search?qwordpress 具体速度慢的问题如下&#xff1a; 现在打开docker右上角的设置图标&#xff0c;并进入docker engine&#xff0c;添加如下代码&#xff1a; "registry-mirrors&…

贪心算法----摆动序列

今日题目&#xff1a;leetcode376 点击跳转题目 观察样例2&#xff1a; 发现最长摆动序列都是极大值和极小值 再加上两个端点&#xff0c;那么我们保证每次都能选择到每个极值点&#xff0c;就能从局部最优推广全局最优了&#xff01; 但是还有一些细节情况需要注意&#xff…

社工库信息查询

此网站需要注册账号&#xff0c;新用户注册送3点券&#xff0c;每日签到可获得1.5点券。也可通过充值来查 我这里有方法可以利用缺陷来无限获取点券查人

土地档案管理关系参考论文(论文 + 源码)

【免费】javaEE土地档案管理系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89296786 土地档案管理关系 摘 要 研究土地档案管理关系即为实现一个土地档案管理系统。土地档案管理系统是将现有的历史纸质档案资料进行数字化加工处理&#xff0c;建成标准化的…

LoRa模块学习

什么是LoRa调制 LoRa&#xff08;Long Range&#xff0c;远距离&#xff09;是一种调制技术&#xff0c;与同类技术相比&#xff0c;提供更长的通信距离。调制是基于扩频技术&#xff0c;线性调制扩频&#xff08;CSS&#xff09;的一个变种&#xff0c;具有前向纠错&#xff…

C++数据结构之链表树图的存储

本文主要介绍用数组存储&#xff0c;结构只做简单介绍 目录 文章目录 前言 结构体实现 1、链表的存储 2、树的存储 3、图的存储 数组实现 1、链表实现 2、树和图的实现 总结 前言 在正常工程中&#xff0c;我们通常使用结构体或者类&#xff0c;来定义并使用如链表…

1_1. Linux简介

1_1. Linux简介 文章目录 1_1. Linux简介1. 我们用linux来干嘛2. 计算机组成3. 操作系统4. Linux哲学思想5. Linux目录6. Linux分区类型 1. 我们用linux来干嘛 1. 大家都知道linux是一个操作系统&#xff0c;它是一个基础的软件&#xff0c;操作系统是硬件与应用程序的中间层。…

音频—WAV格式及写入wav文件代码实现

1.RIFF规范 FIFF 是 Resource Interchange File Format&#xff08;资源交换文件格式&#xff09;的简称。RIFF 是一种文件格式规范&#xff0c;用于在计算机系统之间交换和存储多媒体资源。WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集。 RIFF 规则定义了文件的结构和数…

PyQt6--Python桌面开发(7.QTextEdit多行富文本框控件)

QTextEdit多行富文本框控件 保存文件到本地QLine多行文本框.ui import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit,QTextEdit from PyQt6 import uic,QtGuiif __name__ __main__:appQApp…

视频监控系统中,中心录像服务器的录像文件实际大小和理论值相差很大的问题解决

目录 一、现象描述 二、视频监控的录像文件计算 &#xff08;一&#xff09;计算方法 1、仅视频部分 2、视频和音频部分 3、使用平均码率 &#xff08;二&#xff09;计算工具 1、关注威迪斯特公众号 2、打开“计算容量”的小工具 三、原因分析 &#xff08;一&…

超级好看的html网站维护源码

源码介绍 好看的html网站维护源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c; 源码截图 源码下载 好看的html网站维护源码

Codeforces Round 605 (Div. 3) A~D

本人水平不高&#xff0c;开这个专栏主要是督促自己补题&#xff0c;有些题对目前的我来说还比较难&#xff0c;还补不动&#xff0c;等以后能力上来了再补。。。 原题链接&#xff1a;Dashboard - Codeforces Round 605 (Div. 3) - Codeforces 目录 A. Three Friends B. Sn…

Leedcode题目:移除链表元素

题目&#xff1a; 这个题目就是要我们将我们的链表中的值是val的节点删除。 我们题目提供的接口是 传入了指向一个链表的第一个节点的指针&#xff0c;和我们要删除的元素的值val&#xff0c;不只要删除第一个&#xff0c; 思路 我们这里可以创建一个新的链表&#xff0c;…

第四百九十九回

文章目录 1. 概念介绍2. 使用方法2.1 固定样式2.2 自定义样式 3. 示例代码4. 内容总结 我们在上一章回中介绍了"GetMaterialApp组件"相关的内容&#xff0c;本章回中将介绍使用get显示SnackBar.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在介…