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

news2024/9/20 16:55:18

文章目录

    • (十二) 文件
      • 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;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytest + yaml 框架 - 录制接口转 yaml 用例实现

pytest yaml 框架基本不用写 python 代码&#xff0c;只需写yaml 文件用例就能实现接口自动化。 现在引入接口录制功能&#xff0c;连 yaml 文件也不用写了&#xff0c;点点点就能生成 yaml 用例文件了。 录制功能在v1.3.4版本上实现 pip instal pytest-yaml-yoyo 环境准备 …

string类的介绍与使用【C++】

string类 前言一、为什么学习string类C语言中的字符串示例 二、标准库中的string类string类string类的常用接口说明string类对象的常见构造string类对象的容量操作string的接口测试及使用string类对象的访问及遍历操作下标和方括号遍历范围for遍历迭代器遍历相同的代码&#xf…

Seaborn : 超好用的Python可视化工具

1. 引言 说到数据可视化&#xff0c;Seaborn就像一颗隐藏的宝石&#xff01;在进行探索性数据分析时&#xff0c;我们通常从Matplotlib 开始&#xff0c;而对 Seaborn 的探索相对较少&#xff01;但是&#xff0c;只要你了解 Seaborn 的全部潜力&#xff0c;你就会惊奇地发现&…

半小时搞懂STM32面经知识点——IIC

1.IIC 1.1什么是IIC&#xff1f; 同步半双工通信协议&#xff0c;适用于小数据和短距离传输。 1.2 IIC需要几条线&#xff1f; IIC总共有2条通信总线&#xff08;SDA,SCL&#xff09;&#xff0c;SCL为时钟同步线&#xff0c;用于主机和从机间数据同步操作&#xff1b;SDA为…

Qt开发常见报错大全与解决办法

下面的报错是我日常开发经常遇到的,对着下面的解决方法一招搞定就行了。 我们没必要都去记住,只需要见方抓药即可。 目前版本有27个常见报错,持续更新中。 常见报错 翻译不起作用 你可能改了类名字,但是.ts文件里没有跟着改。 Cannot send events to objects owned by a…

多线程-线程安全

目录 线程安全问题 加锁(synchronized) synchronized 使用方法 synchronized的其他使用方法 synchronized 重要特性(可重入的) 死锁的问题 对 2> 提出问题 对 3> 提出问题 解决死锁 对 2> 进行解答 对4> 进行解答 volatile 关键字 wait 和 notify (重要…

线下研讨会 技术沙龙|乐鑫芯片与 ESP RainMaker® 为科技初创企业赋能

众多科技初创企业在智能硬件市场迅猛发展的背景下&#xff0c;对不断变化的需求展现出了高度的敏锐性&#xff0c;期望能够快速将其转化为切实的产品方案。然而&#xff0c;面对复杂繁重的软硬件集成任务&#xff0c;这些企业往往容易陷入研发瓶颈、资金短缺以及效率低下等多重…

Mybatis技术内幕-基础支撑层

整体架构 MyBatis 的整体架构分为三层&#xff0c; 分别是基础支持层、核心处理层和接口层。 基础支持层 基础支持层包含整个MyBatis 的基础模块&#xff0c;这些模块为核心处理层的功能提供了良好的支撑。 解析器模块 XPathParser MyBatis提供的XPathParser 类封装了XPat…

HackMyVM-Minimal

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 gobuster 文件包含漏洞 提权 web信息收集 main方法 question_1 question_2 question_3 prize.txt 软连接 信息收集 arp ┌──(root?0x00)-[~/HackMyVM] └─# arp-scan -l Interface: eth0, type: E…

centos7.9系统安全加固

1、限制用户登陆 vim /etc/hosts.deny&#xff0c;若禁止192.168.0.158对服务器进行ssh的登陆&#xff0c;添加如下内容 sshd : 192.168.0.158 添加完毕后就生效了&#xff0c;直接用192.168.0.158访问主机&#xff0c;就无法连接了&#xff0c;显示 Connection closing...Soc…

pycharm报错Process finished with exit code -1073740791 (0xC0000409)

pycharm报错Process finished with exit code -1073740791 (0xC0000409) 各种垃圾文章&#xff08;包括chatgpt产生的垃圾文章&#xff09;&#xff0c;没有给出具体的解决办法。 解决办法就是把具体报错信息显示出来&#xff0c;然后再去查。 勾选 然后再运行就能把错误显示…

图像分割各种算子算法-可直接使用(Canny、Roberts、Sobel)

Canny算子&#xff1a; import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg cv.imread("../test_1_1.png") edges cv.Canny(img, 100, 200)plt.subplot(121),plt.imshow(img,cmap gray) plt.title(Original Image), plt.xticks([]), …

vue2+swiper——实现多图轮播+层叠轮播——技能提升

今天看到同事在写轮播图&#xff0c;由于是jq的写法&#xff0c;我没有过多参与&#xff0c;我只写vue的部分。。。虽然语言不一样&#xff0c;但是用法还是要会的。下面介绍通过swiper组件来实现轮播效果。 解决步骤1&#xff1a;安装swiper npm install swiper5.4.5 我这边…

数据分享—全国分省河流水系

河流水系数据是日常研究中必备的数据之一&#xff0c;本期推文主要分享全国分省份的水系和河流数据&#xff0c;梧桐君会不定期的更新数据&#xff0c;欢迎长期订阅。 数据预览 山东省河流水系 吉林省河流水系 四川省河流水系 数据获取方式 链接&#xff1a;https://pan.baidu.…

基于阿里云向量检索 Milvus 版与 PAI 搭建高效的检索增强生成(RAG)系统

阿里云向量检索 Milvus 版现已无缝集成于阿里云 PAI 平台&#xff0c;一站式赋能用户构建高性能的检索增强生成&#xff08;RAG&#xff09;系统。您可以利用 Milvus 作为向量数据的实时存储与检索核心&#xff0c;高效结合 PAI 和 LangChain 技术栈&#xff0c;实现从理论到实…

网络基础(三)——网络层

目录 IP协议 1、基本概念 2、协议头格式 2.1、报头和载荷如何有效分离 2.2、如果超过了MAC的规定&#xff0c;IP应该如何做呢&#xff1f; 2.3、分片会有什么影响 3、网段划分 4、特殊的ip地址 5、ip地址的数量限制 6、私有ip地址和公网ip地址 7、路由 IP协议 网络…

LINUX 精通 1——2.1.1 网络io与io多路复用select/poll/epoll

LINUX 精通 1 day12 20240509 算法刷题&#xff1a; 2道高精度 耗时 107min 课程补20240430 耗时&#xff1a;99 min day 13 20240512 耗时&#xff1a;200min 课程链接地址 前言 杂 工作5-10年 够用 费曼&#xff1a;不要直接抄&#xff0c;自己写&#xff1b;不要一个…

【微服务】spring aop实现接口参数变更前后对比和日志记录

目录 一、前言 二、spring aop概述 2.1 什么是spring aop 2.2 spring aop特点 2.3 spring aop应用场景 三、spring aop处理通用日志场景 3.1 系统日志类型 3.2 微服务场景下通用日志记录解决方案 3.2.1 手动记录 3.2.2 异步队列es 3.2.3 使用过滤器或拦截器 3.2.4 使…

安全工程师面试题

安全工程师面试题安全工程师是一个非常重要的职位&#xff0c;他们负责保护公司的网络和系统免受黑客和恶意软件的攻击。如果你想成为一名安全工程师&#xff0c;那么你需要准备好面试。下面是一… 1安全工程师面试题 安全工程师是一个非常重要的职位&#xff0c;他们负责保护…

【全开源】Java俱乐部系统社区论坛商城系统源码-奔驰奥迪保时捷大众宝马等汽车俱乐部

特色功能&#xff1a; 会员中心&#xff1a;会员中心可以帮助企业更好地管理客户&#xff0c;包括设置积分商城、会员卡充值、个人汽车档案等功能&#xff0c;对不同的会员群体展开有针对性的营销&#xff0c;并维护和积累自己的粉丝群体。信息服务&#xff1a;负责定期发布新…