C语言进阶 13. 文件

news2024/9/23 3:22:32

C语言进阶 13. 文件

文章目录

  • C语言进阶 13. 文件
    • 13.1. 格式化输入输出
    • 13.2. 文件输入输出
    • 13.3. 二进制文件
    • 13.4. 按位运算
    • 13.5. 移位运算
    • 13.6. 位运算例子
    • 13.7. 位段

13.1. 格式化输入输出

  • 格式化输入输出:

    • printf
      • %[flags][width][.prec][hlL]type
    • scanf
      • %[flags]type
  • %[flags][width][.prec][hlL]type:

    	flags	含义
    	-		左对齐
    	+		在前面放+-
    	(space)	正数留空
    	0		0填充
    
    
    	width或prec	含义
    	number		最小字符数
    	*			下一个参数是字符数
    	.number		小数点后的数字
    	.*			下一个参数是小数点后的位数
    
    
    	hlL		含义
    	hh		单个字节byte
    	h		short
    	l		long
    	ll		long long
    	L		long double
    
    	type	用于
    	i或d	int
    	u		unsigned int
    	o		八进制
    	x		十六进制
    	X		字母大写的十六进制
    	f或F	float
    	e或E	指数
    	g		float
    	G		float
    	a或A	十六进制
    	c		char
    	s		字符串
    	p		指针
    	n		读入/写出的个数
    
  • scanf: %[flags]type:

    	flag	含义
    	*		跳过
    	数字	最大字符数
    	hh		char
    	h		short
    	l		long double
    	ll		long long
    	L		long double
    
    
    	type	用于
    	d		int
    	i		int, 可以为十六进制或八进制
    	u		unsigned int
    	o		八进制
    	x		十六进制
    	a,e,f,g	float
    	c		char
    	s		字符串
    	p		指针
    	[...]	所允许的字符
    	[^,]	读到,为止
    
  • printf和scanf的返回值:

    • 读入的项目数

    • 输出的字符数

    • 在要求严格的程序中, 应该判断每次调用scanf或printf的返回值, 从而了解程序运行中是否存在问题

#include <stdio.h>

int main(int argc, char const* argv[]) {
	//printf("%9d", 123); //      123
	//printf("h\n");
	//printf("%-9d\n", 123);//123

	//printf("%+d\n", 123); //+123
	//printf("% d\n", 123); // 123
	//printf("%09d\n", 123);//000000123


	//printf("%9.2f\n", 123.0);//   123.00
	//printf("%*d\n", 6, 123); //   123
	//printf("%*.*f\n", 6, 2, 123.0);//123.00

	

	//printf("%hhd\n", 12345);//57, 只取了1byte, 前面的位全部省去

	//int num;
	//scanf("%*d%d", &num);//1 2
	//printf("%d\n", num);//2

	//int num2;
	//scanf("%i", &num2);//0x12
	//printf("%d\n", num2);//18


	//char s[10];
	//char s2[10];
	//char s3[10];
	//scanf("%[^,], %[^,], %[^,]", s, s2, s3);//1,2,3,
	//printf("%s %s %s\n", s, s2, s3);//1 2 3

	int num;
	int i1 = scanf("%d", &num);//123
	int i2 = printf("%d\n", num);//123
	printf("%d:%d\n", i1, i2);//1:4
	return 0;
}

13.2. 文件输入输出

  • 重定向没听懂

  • 文件输入输出:

    • 用>和<做重定向

    • 使用Linux和Windows系统的命令行都可以使用这种方式

      > D:\C语言\C_code\Two_Advanced\13.File\13.0

  • FILE:

    • 打开文件的标准代码
    	FILE* fp = fopen("fileName", "r");	//r: 只读	fopen: 没有打开返回NULL
    	if (fp) {
    		int num;
    		fscanf(fp, "%d", &num);
    		printf("%d\n", num);
    		fclose(fp);
    	}
    	else {
    		printf("无法打开文件\n");
    	}
    
  • fopen:

    	fopen("参数1", "参数2");
    	参数1: 文件名
    	参数2:
    		r	只读
    		r+	读写, 从文件头开始
    		w	只写, 如果不存在则新建, 如果存在则清空
    		w+	读写, 如果不存在则新建, 如果存在则清空
    		a	追加, 如果不存在则新建, 如果存在则从文件尾开始
    	   ..x	只新建, 如果文件已存在则不能打开
    
#include <stdio.h>
#include <string.h>

int main(int argc, char const* argv[]) {
	FILE* fp = fopen("a.txt", "r");
	if (fp) {
		int num;
		fscanf(fp, "%d", &num);
		printf("%d\n", num);
		fclose(fp);
	}
	else {
		printf("无法打开文件\n");
	}
	return 0;
}

13.3. 二进制文件

  • 后面的没听懂

  • 二进制文件:

    • 其实所有的文件最终都是二进制的

    • 文本文件无非是用最简单的方式可以读写的文件

      • more, tail
      • cat
      • vi
    • 而二进制文件是需要专门的程序来读写的文件

    • 文本文件的输入输出是格式化, 可能经过转码

  • 文本 VS 二进制:

    • Unix喜欢用文本文件来做数据存储和程序配置

      • 交互式终端的出现使得人们喜欢用文本和计算机"talk"
      • Unix的shell提供了一些读写文本的小程序
    • Windows喜欢用二进制文件

      • DOS是草根文化, 并不继承和熟悉Unix文化
      • PC刚开始的时候能力有限, DOS的能力更有限, 二进制更接近底层
  • 优缺点:

    • 文本

      • 优势是方便认类读写, 而且跨平台
      • 缺点是程序输入输出要经过格式化, 开销大
    • 二进制

      • 缺点是认类读写困难, 而且不跨平台
        • int的大小不一致, 大小端的问题…
      • 优点是程序读写快
  • 程序为什么要文件:

    • 配置

      • Unix用文本, Windows用注册表
    • 数据

      • 稍微有点量的数据都放数据库了
    • 媒体

      • 这个只能是二进制的
    • 现实是, 程序通过第三方库来读写文件, 很少直接读写二进制文件了

  • 二进制读写:

    size_t fread(void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream);
    					读写的内存,		一个的大小,		一共多少个,			文件指针
    
    size_t fwrite(const void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream);
    
    注意FILE指针是最后一个参数
    	
    返回的是成功读写的字节数
    
  • 为什么nitem?

    • 因为二进制文件的读写一般都是通过哟对一个结构变量的操作来进行的

    • 于是nitem就是用来说明这次读写几个结构变量

  • 在文件中定位:

    	long ftell(FILE* stream);
    	
    	int fseek(FILE* stream, long offset, int whence);
    		SEEK_SET: 从头开始
    		SEEK_CUR: 从当前位置开始
    		SEEK_END:从尾开始(倒过来)
    
  • 可移植性:

    • 这样的二进制文件不具有可移植性

      • 在int为32位的机器上写成的数据文件无法直接在int为64位的机器上正确的读出
    • 解决方案之一是放弃使用int, 而是typedef具有明确大小的类型

    • 更好的方案是文本

13.4. 按位运算

  • 按位运算:

    • C有这些按位运算的运算符, 位指的是二进制位
    	&	按位与
    	|	按位或
    	~	按位取反
    	^	按位异或
    	<<	左移
    	>>	右移
    
  • 按位与&:

    • 如果(x)i == 1 并且 (y)i == 1, 那么(x & y)i = 1

    • 否则(x & y)i = 0

    • 按位与常用于两种应用

      • 让某一位或某些位为0: x & 0xFE
      • 取一个数中的一段: x & 0xFF
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
  • 按位或|:

    • 如果(x)i == 1 或 (y)i == 1, 那么(x | y)i = 1

    • 否则(x | y)i = 0

    • 按位或常用于两种应用

      • 使得一位或几个位为1: x | 0x01
      • 把两个数拼起来: 0x00FF | 0xFF00
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
  • 按位取反~:

    • (~x)i = 1 - (x)i
      • 把1位变0, 0位变1

      • 想得到全部位为1的数: ~0

      • 7的二进制是0111, x | 7 使得低3位为1

      • x & ~7, 就使得低3位为0
        在这里插入图片描述

  • 逻辑运算 VS 按位运算:

    • 对于逻辑运算, 它只看到两个值: 0和1

    • 可以认为逻辑运算相当于把所有非0值都变成1, 然后做按位运算

      	5 & 4 -> 4 而 5 && 4 -> 1 & 1 -> 1
      	5 | 4 -> 5 而 5 || 4 -> 1 | 1 -> 1
      	~4 -> -5 而 !4 -> !1 -> 0
      
  • 按位异或:

    • 如果(x)i == (y)i, 那么(x ^ y)i = 0

    • 否则(x ^ y)i = 1

    • 如果两个位相等, 那么结果为0, 不相等, 结果为1

    • 如果x和y相等, 那么x^y的结果为0

    • 对一个变量用同一个值异或两次, 等于什么也没做

      • x^y^y -> x
        在这里插入图片描述
#include <stdio.h>

int main(int argc, char const* argv[]) {
	unsigned char c = 0xAA;
	printf(" c = %hhx\n", c);// c = aa
	printf("~c = %hhx\n", (char)~c);//~c = 55
	printf("-c = %hhx\n", (char)-c);//-c = 56

	printf("%d\n", ~5);
	return 0;
}

13.5. 移位运算

  • 左移<<:

    • i << j

    • i中所有的位向左移j个位置, 而右边填入0

    • 所有小于int的类型, 移位以int的方式来做, 结果是int

    • x << 1 等价于 x *= 2

    • x << n 等价于 x *= 2^n
      在这里插入图片描述

  • 右移>>:

    • i << j

    • i中所有的位向右移j个位置

    • 所有小于int的类型, 移位以int的方式来做, 结果是int

    • 对于unsigned的类型, 左边填入0

    • 对于signed的类型, 左边填入原来的最高位(保持符号位不变)

    • x << 1 等价于 x *= 2

    • x << n 等价于 x *= 2^n

  • no zuo no die:

    • 移位的位数不要用负数, 这是没有定义的行为
      • x << -2 //!!NO!!
#include <stdio.h>

int main(int argc, char const* argv[]) {
	//unsigned char a = 0xA5;
	//int n;
	//scanf("%d", &n);
	//printf("a = %hhx\n", a);//a = a5
	//printf("a << 2 == %hhx\n", a << 2);//a << 2 == 94

	//printf("a = %d\n", a);//a = 165
	//printf("a << 2 == %d\n", a << 2);//a << 2 == 660

	//printf("a << n == %d\n", a << n);


	int a = 0x80000000;
	//1000000000...000
	//11000000000...000



	unsigned int b = 0x80000000;
	printf("a = %d\n", a);//a = -2147483648
	printf("b = %u\n", b);//b = 2147483648

	printf("a >> 1 = %d\n", a >> 1);//a >> 1 = -1073741824
	printf("b >> 1 = %u\n", b >> 1);//b >> 1 = 1073741824
	return 0;
}

13.6. 位运算例子

  • 后面讲的单片机部分不会

  • 输出一个数的二进制:

  • 跟着视频写的

//10000000000000000000000000000000
//000000000000000000000000000000001
//00000000000000000000000000011110

#include <stdio.h>

int main(int argc, char const* argv[]) {
	int num;
	scanf("%x", &num);
	//向左移31位, 这样最高位就变成了1
	unsigned int mask = 1u << 31;
	//每次循环让这个1右移1位, 直到mask为0
	for (; mask; mask >>= 1) {
		//num与mask, 循环遇到num出现1的位时, 输出1, 为0输出0
		printf("%d", num & mask ? 1 : 0);
	}
	printf("\n");
	return 0;
}

13.7. 位段

  • 听不懂
  • 位段:
    • 把一个int的若干位组合成一个结构

      struct {
      	unsigned int leading : 3;
      	unsigned int FLAG1 : 1;
      	unsigned int FLAG2 : 2;
      	int trailing : 11;
      };
      
    • 可以直接用位段的成员名称来访问

      • 比移位, 与, 或还方便
    • 编译器会按排其中的位的排列, 不具有可移植性

    • 当所需的位超过一个int时会采用多个int

#include <stdio.h>

void prtBin(unsigned int num);

struct U0 {
	unsigned int leading : 3;//成员leading后面加上一个冒号和一个3, 意思是成员leading占了3个bit
	unsigned int FLAG1 : 1;
	unsigned int FLAG2 : 2;
	int trailing : 32;
};

int main(int argc, char const* argv[]) {
	struct U0 uu;
	uu.leading = 2;
	uu.FLAG1 = 0;
	uu.FLAG2 = 1;
	uu.trailing = 0;
	printf("sizeof(uu) = %lu\n", sizeof(uu));
	prtBin(*(int*)&uu);
	return 0;
}

void prtBin(unsigned int num) {
	unsigned mask = 1u << 31;
	for (; mask; mask >>= 1) {
		printf("%d", num & mask ? 1 : 0);
	}
	printf("\n");
}

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

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

相关文章

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用 本数据为空中及地面拍摄道路病害检测检测数据集&#xff0c;数据集数量如下&#xff1a; 总共有:33585张 训练集&#xff1a;6798张 验证集&#xff1a;3284张 测试集&a…

视频监控国标GB28181平台EasyGBS如何更换默认的SQLite数据库?

视频流媒体安防监控国标GB28181平台EasyGBS视频能力丰富&#xff0c;部署灵活&#xff0c;既能作为业务平台使用&#xff0c;也能作为安防监控视频能力层被业务管理平台调用。国标GB28181视频EasyGBS平台可提供流媒体接入、处理、转发等服务&#xff0c;支持内网、公网的安防视…

数据集相关类代码回顾理解 | np.mean\transforms.Normalize\transforms.Compose\xxx.transform

数据集相关类代码回顾理解 | StratifiedShuffleSplit\transforms.ToTensor\Counter 目录 np.mean transforms.Normalize transforms.Compose xxx.transform np.mean meanRGB[np.mean(x.numpy(),axis(1,2)) for x,_ in train_ds] 计算每个样本的&#xff08;RGB&#xff0…

鸿蒙应用框架开发【JS注入与执行】 Web

JS注入与执行 介绍 本示例基于H5游戏&#xff0c;通过arkui的button实现对游戏实现基本控制&#xff0c;展示webview的JS注入与执行能力&#xff0c;及native应用与H5的通信能力。 效果预览 使用说明 1.设备连接热点&#xff0c;可访问互联网。 2.打开应用&#xff0c;通过…

【Java】如何避免超预期的高并发压力压垮系统?

一、问题解析 在互联网高可用架构设计中&#xff0c;限流是一种经典的高可用架构模式。因为某些原因&#xff0c;大量用户突然访问我们的系统时&#xff0c;或者有黑客恶意用DoS&#xff08;Denial of Service&#xff0c;拒绝服务&#xff09;方式攻击我们的系统时&#xff0…

oracle表、表空间使用空间

文章目录 一、Oracle查询表空间占用情况二、Oracle查询表占用的空间三、Oracle查询表空间使用情况四、Oracle查询每张表占用空间五、表空间大小 TOC 一、Oracle查询表空间占用情况 oracle日常工作中查看表占用空间大小是数据库管理中的基本操作&#xff1a; SELECT a.tablesp…

大龄程序员转型攻略:拥抱人工智能,开启新征程

前言 随着科技的飞速发展&#xff0c;人工智能浪潮席卷全球&#xff0c;相关岗位炙手可热。在这个背景下&#xff0c;许多大龄程序员开始思考如何转型&#xff0c;以适应时代的变化。结合自身编程基础&#xff0c;大龄程序员可以学习机器学习、深度学习算法&#xff0c;投身于…

MySQL 高性能索引使用策略

文章目录 前置知识表准备一. 不在索引列上使用任何操作二. 联合索引字段列全值匹配三. 最佳左前缀法则四. 范围条件放最后五. 覆盖索引使用六. 不等于导致索引失效七. is null/not null 影响八. like 查询的使用九. 字符类型加引号十. OR关键字前后索引问题十一. 利用索引来做排…

昇思25天学习打卡营第XX天|Pix2Pix实现图像转换

Pix2Pix是一种基于条件生成对抗网络&#xff08;cGAN&#xff09;的图像转换模型&#xff0c;由Isola等人在2017年提出。它能够实现多种图像到图像的转换任务&#xff0c;如从草图到彩色图像、从白天到夜晚的场景变换等。与传统专用机器学习方法不同&#xff0c;Pix2Pix提供了一…

【Dart 教程系列第 49 篇】什么是策略设计模式?如何在 Dart 中使用策略设计模式

这是【Dart 教程系列第 49 篇】&#xff0c;如果觉得有用的话&#xff0c;欢迎关注专栏。 博文当前所用 Flutter SDK&#xff1a;3.22.1、Dart SDK&#xff1a;3.4.1 文章目录 一&#xff1a;什么是策略设计模式&#xff1f;二&#xff1a;为什么要使用策略设计模式&#xff1…

pytest框架的作用--面试

在做接口自动化的时候我们经常会用到pytest这个框架&#xff0c;这个框架有哪些优点 1. 帮我们找到用例 模块名必须以test_开头&#xff1b;类名必须以Test开头&#xff0c;并且不能有init方法&#xff1b;用例方法必须以test开头 2.执行用例 有很多参数设置执行 3. 断言-可以…

大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

昇思25天学习打卡营第XX天|07-函数式自动微分

本章分为两类&#xff0c;一神经网络训练依赖反向传播算法&#xff0c;通过损失函数计算预测值与标签间的误差&#xff0c;反向传播求得梯度&#xff0c;进而更新模型参数。 二、自动微分简化了这一过程&#xff0c;将复杂运算分解为基础运算&#xff0c;隐藏了求导细节&#…

重新思考终端 LLMs 和 Agents

0x0 前言 LLM (Large Language Models) 的风头一时无两&#xff0c;席卷万千行业。业内不乏有关于 LLM 的研究和讨论&#xff0c;但鲜有立足终端的视角。团队上半年曾有过对 GPT 进终端的分析&#xff0c;但 LLM 日新月异&#xff0c;旧分析已经不完全跟得上变化了。适逢年底规…

达飞集团全新互联网投融资平台即将隆重上线

全球知名海运和物流巨头达飞集团(CMA CGM)即将推出其最新力作——全新互联网投融资平台。该平台旨在为投资者提供安全、稳定且高效的投资机会,通过筹集资金支持全球各地实体产业项目的落地建设。这一举措不仅展现了达飞集团在金融科技领域的创新能力,也彰显了其在海运和物流行业…

C# Solidworks二次开发------信息提示

一、内容 对于信息提示主要有两种方式。 方式一&#xff1a;Solidworks自带的提示 方式二&#xff1a;C#中的消息提示 二、代码 ISldWorks swApp Activator.CreateInstance(Type.GetTypeFromProgID("SldWorks.Application")) as SldWorks; swApp.NewPart(); ModelD…

懂个锤子Vue 自定义指定、插槽:

Vue自定义指定、插槽&#x1f6e0;️&#xff1a; 前言&#xff1a;当然既然学习框架的了&#xff0c;HTMLCSSJS三件套必须的就不说了&#xff1a; JavaScript 快速入门 紧跟前文&#xff0c;目标学习Vue2.0——3.0&#xff1a; 懂个锤子Vue、WebPack5.0、WebPack高级进阶 涉…

npm与webpack的学习笔记

npm 定义&#xff1a;npm是Node.js标准的软件包管理器。它起初是作为下载和管理Node.js包依赖的方式&#xff0c;但其现在也已成为前端JavaScript中使用的工具。 包 包&#xff1a;将模块、代码、其他资料聚合成一个文件夹 包的分类&#xff1a; 项目包&#xff1a;主要用…

upload-labs-靶场(1-19关详细解答 保姆级教程)

Pass-01 下载 upload-labs-mster靶场 创建一个upload目录 不然无法打开upload-labs 靶场 1.我们先上传一个 php后缀文件 显示我们该文件不允许上传 只能上传 jpg png gif的文件后缀 2.我们可以上传 自己写的php 后缀改成jpg上传 然后抓包 可以看到 数据上传了 我们可以在burps…

5.缓存雪崩问题及解决思路

缓存雪崩问题及解决思路 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 解决方案&#xff1a; 给不同的Key的TTL添加随机值利用Redis集群提高服务的可用性给缓存业务添加降级限流策略给业务添…