C语言进阶 13. 文件

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		单个字节byteh		shortl		longll		long longL		long doubletype	用于i或d	intu		unsigned into		八进制x		十六进制X		字母大写的十六进制f或F	floate或E	指数g		floatG		floata或A	十六进制c		chars		字符串p		指针n		读入/写出的个数
    
  • scanf: %[flags]type:

    	flag	含义*		跳过数字	最大字符数hh		charh		shortl		long doublell		long longL		long doubletype	用于d		inti		int, 可以为十六进制或八进制u		unsigned into		八进制x		十六进制a,e,f,g	floatc		chars		字符串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 3int num;int i1 = scanf("%d", &num);//123int i2 = printf("%d\n", num);//123printf("%d:%d\n", i1, i2);//1:4return 0;
}

13.2. 文件输入输出

  • 重定向没听懂

  • 文件输入输出:

    • 用>和<做重定向

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

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

  • FILE:

    • 打开文件的标准代码
    	FILE* fp = fopen("fileName", "r");	//r: 只读	fopen: 没有打开返回NULLif (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 -> 15 | 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 = aaprintf("~c = %hhx\n", (char)~c);//~c = 55printf("-c = %hhx\n", (char)-c);//-c = 56printf("%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...000unsigned int b = 0x80000000;printf("a = %d\n", a);//a = -2147483648printf("b = %u\n", b);//b = 2147483648printf("a >> 1 = %d\n", a >> 1);//a >> 1 = -1073741824printf("b >> 1 = %u\n", b >> 1);//b >> 1 = 1073741824return 0;
}

13.6. 位运算例子

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

  • 输出一个数的二进制:

  • 跟着视频写的

//10000000000000000000000000000000
//000000000000000000000000000000001
//00000000000000000000000000011110#include <stdio.h>int main(int argc, char const* argv[]) {int num;scanf("%x", &num);//向左移31位, 这样最高位就变成了1unsigned int mask = 1u << 31;//每次循环让这个1右移1位, 直到mask为0for (; mask; mask >>= 1) {//num与mask, 循环遇到num出现1的位时, 输出1, 为0输出0printf("%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个bitunsigned 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://xiahunao.cn/news/3280027.html

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

相关文章

Spring Boot:SpringBoot入门

本文是跟着B站"黑马程序员"up主的SpringBoot3vue3的视频的学习过程记录&#xff0c;仅用于学习记录 视频里的图&#xff1a; 呃。。。。都没有学过这些。。。。。 不管了&#xff0c;先学。。。。。。入门&#xff1a; 创建Maven工程 导入spring-boot-stater-web起…

AI测试:人工智能模型的核心测试指标,分类判别、目标检测、图像分割、定量计算分别有哪些指标?

在前面的人工智能测试技术系列文章中&#xff0c;我们详细介绍了人工智能测试的技术方法和实践流程。在了解人工智能测试方法后&#xff0c;我们需要进一步学习和研究如何衡量这些方法的有效性&#xff0c;即人工智能模型测试指标的选择。测试指标的选择主要取决于模型的类型和…

MySQL基础练习题15-进店却未进行交易过的顾客

题目&#xff1a;有一些顾客可能光顾了购物中心但没有进行交易。来查找这些顾客的 ID &#xff0c;以及他们只光顾不交易的次数。 准备数据 分析数据 题目&#xff1a;有一些顾客可能光顾了购物中心但没有进行交易。来查找这些顾客的 ID &#xff0c;以及他们只光顾不交易的次…

介绍五款广受好评的企业级加密软件

在当今信息化时代&#xff0c;数据安全已成为企业管理的重要环节。随着网络攻击和数据泄露事件的频繁发生&#xff0c;如何有效保护企业数据不被泄露&#xff0c;成为各大企业关注的焦点。加密软件作为一种有效的防护工具&#xff0c;通过对数据进行加密处理&#xff0c;确保敏…

最好用的复制粘贴软件pastemate功能简介

这应当是windows下最好用的复制粘贴软件&#xff0c;遥遥领先的复制粘贴软件。 效增PasteMate - 下载页面 windows下界面最优美&#xff0c;操作最方便的复制粘贴神器&#xff0c;学生党论文必备&#xff0c;效率神器 pastemate 1.搜索功能&#xff0c;能够按文本、图片、文件…

AI多模态模型架构之输出映射器:Output Projector

〔探索AI的无限可能&#xff0c;微信关注“AIGCmagic”公众号&#xff0c;让AIGC科技点亮生活〕 本文作者&#xff1a;AIGCmagic社区 刘一手 前言 AI多模态大模型发展至今&#xff0c;每年都有非常优秀的工作产出&#xff0c;按照当前模型设计思路&#xff0c;多模态大模型的…

解析和解决Protobuf数据传输中的字段错位问题

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…

【Linux】全志Tina etc目录下关键文件内容修改

一、文件位置 V:\f1c100s\Evenurs\f1c100s\tina\target\allwinner\c200s-F1C200s\busybox-init-base-files\etc\ssv6x5x-wifi.cfg 二、文件内容 三、介绍 在此目录下&#xff0c;可以修改在etc目录下的文件内容&#xff0c;此处举例修改一个wifi模块的配置文件数据。

【前端 20】Element-UI快速入门

探索Element UI组件库&#xff1a;快速搭建Vue应用的必备工具 在现代Web开发中&#xff0c;Vue.js以其轻量级和灵活性赢得了广泛的关注。而Element UI&#xff0c;作为Vue.js的一个UI组件库&#xff0c;更是为开发者们提供了丰富、易用的前端组件&#xff0c;极大地加速了开发过…

【Spring】——Spring概述、IOC、IOC创建对象的方式、Spring配置、依赖注入(DI)以及自动装配知识

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

前端vue3 巧妙的checkbox 选中框样式

我们 做前端页面交互效果的时候 我们会使用到 checkbox 复选框 做一些交互的效果 我是用的是 nut-ui 组件库中的 checkbox 组件 类似于这样的选中效果 假如 二选一的那种 可以 这样写 交互好看 而不是单纯的 checkbox 框 这里我就不使用 gif 图片了 大家应该都可以看懂的 …

操作系统课程设计:(JAVA)进程管理系统(附源码zip,jdk11,IDEA Ultimate2024 )

一.题目要求描述 本设计的目的是加深对进程概念及进程管理各部分内容的理解&#xff1b;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。要求设计一个允许n个进程并发运行的进程管理模拟系统。 该系统包括有简单的进程控制、同步与…

Spring AOP总结

1、AOP&#xff08;Aspect-Oriented Programming&#xff09;&#xff1a;面向切面编程让开发更高效。 工作中经常需要处理日志记录、事物管理、安全控制等跨越多个业务模块的公共逻辑。 它是一种编程的范式。它通过将跨多个业务模块的公共逻辑抽取并封装成独立的模块&#xf…

微信小程序云开发订单微信支付与小票和标签打印的完整高效流程

一个字“全”&#xff01;&#xff01;&#xff01; 前言一、流程设定1、如何开通云支付流程2、以订单下单为例的支付流程2.1 业务场景介绍2.2 业务场景流程图 二、代码与代码文件组成1、页面JS2、云函数payPre3、支付回调函数pay_cb3.1 准备条件3.2 必要认知3.3 pay_cb 完整函…

Python使用pytest-benchmark做基准测试

安装pytest-benchmark pip install pytest-benchmark代码编写 导入pytest import pytest我们以“在120以内的正整数中找出和120互质的正整数&#xff0c;并统计个数和求和”为例&#xff0c;比较穷举和使用数学技巧完成该任务的性能。 def coprime_120_1():count 0sum 0f…

Java 8-函数式接口

目录 一、概述 二、 函数式接口作为方法的参数 三、函数式接口作为方法的返回值 四、 常用的函数式接口 简单总结 简单示例 4.1 Consumer接口 简单案例 自我练习 实际应用场景 多线程处理 4.2 Supplier接口 简单案例 自我练习 实际应用场景 配置管理 4.3 Func…

MindIE Service服务化集成部署通义千问Qwen模型

一、昇腾开发者平台申请镜像 登录Ascend官网昇腾社区-官网丨昇腾万里 让智能无所不及 二、登录并下载mindie镜像 #登录docker login -u XXX#密码XXX#下载镜像docker pull XXX 三、下载Qwen的镜像 使用wget命令下载Qwen1.5-0.5B-Chat镜像&#xff0c;放在/mnt/Qwen/Qwen1.5-…

将项目部署到docker容器上

通过docker部署前后端项目 前置条件 需要在docker中拉去jdk镜像、nginx镜像 docker pull openjdk:17 #拉取openjdk17镜像 docker pull nginx #拉取nginx镜像部署后端 1.打包后端项目 点击maven插件下面的Lifecycle的package 对后端项目进行打包 等待打包完成即可 2.将打…

源码搭建国内微短剧系统上架(微信抖音)所需资质全面解析

随着短视频和微短剧市场的持续升温&#xff0c;越来越多的企业和个人开始关注并尝试进入这一领域。微短剧以其短小精悍、内容丰富的特点&#xff0c;吸引了大量用户的关注。对于想要搭建并运营自己的微短剧系统的创业者来说&#xff0c;选择合适的平台以及准备必要的资质成为了…

Linux下文件编译器-GCC/G++

前言 本文介绍了c/c的编译过程以及gcc/g的时使用 一.c/c翻译的本质&#xff1a;将高级语言翻译成二进制 1&#xff09;程序翻译过程&#xff1a; &#xff08;1&#xff09;预处理&#xff08;头文件展开、宏替换、去注释、条件编译&#xff09;还是C语言代码 ​ …