I/O:标准IO(二)

news2024/9/27 21:30:57

一、标准IO操作函数

1.fgets、fputs

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

功能描述:将字符串s写入stream指向的文件中

返回数:成功写入文件中数据的字节数

int puts(const char* s)

功能描述:将字符串s写入终端;

返回值:成功写入终端的数据的字节数

char *fgets(char *s, int size, FILE *stream);

功能:从stream指向的文件中,吸收最多size个字节的数据,写入s指向的字符数组中去

返回值:成功吸收返回s,失败返回NULL

吸收最多size个字节,size中包含了1个字节的结束符,所以,最多能吸收的有效字节数为:size-1

使用fgets代替scanf

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

//从终端吸入size-1个有效数据
//使用fgets代替scanf

char *getstr(char *buf,int size){
	char *res=fgets(buf,size,stdin);
	int len=strlen(buf); //获取buf的长度,结束符在len下标上,所以回车就在len-1下标上
	if(buf[len-1]=='\n')//这两句不写的话,就会有两个换行符号
		buf[len-1]='\0';
	return res;
}
int main(int argc, const char *argv[])
{
	char buf[32]="0";
	printf("%s\n",getstr(buf,32));
	return 0;
}

2.fwrite、fread

fwrite和fread是数据流

文件流:任意数据,都会以字符串,然后再以字符串二进制的形式,写入文件中

数据流:所有数据,都以二进制的形式写入文件中

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

功能描述:将ptr指向的内存空间上,总共 size * nmemb 个字节的数据,写入stream指向的文件中

注意:将普通数据写入后,文件中呈现二进制状态

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

功能描述:读取stream指向的文件,总共读取nmemb个数据,每个数据大小为size,将这些数据写入 ptr指向的内存中

注意:fwrite、fread会强制读写 size*nmemb字节的数据,无论是否有那么多数据,成为模块化读写

int feof(FILE *stream);

功能描述:测试stream指向的文件,是否读写到了结束符,如果到了结束符,则返回非0(实际上是1),没到结束符返回0

注意:

1.因为在读取最后一个模块的时候,如果最后一个模块大小,没有我们设定的读取模块那么大的话,就会将文件结束符一起读取到模块里面去,然后通过feof判定文件读取结束,最后个模块就没有通过fwrite写出去

2.如果使用fwrite、fread配合feof去实现文件拷贝功能(一起其他类似的功能)的时候,如果模块大小没有计算精确的话,容易导致最后一个模块出问题

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    FILE* rfp = fopen(argv[1],"r");
    FILE* wfp = fopen(argv[2],"w");
    if(rfp==NULL || wfp==NULL){return 1;}

    char buf[100] = {0};
    while(1){
        fread(buf,100,1,rfp);
        if(feof(rfp)==1){break;}
        fwrite(buf,100,1,wfp);
    }


    fclose(rfp);
    fclose(wfp);
    return 0;
}

3.文件光标偏移函数fseek

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

功能:将stream指向的文件光标进行偏移,偏移量为offset个字节,offset为正表示从左往右偏,为负表示从右往左偏。whence决定偏移的起点

SEEK_SET:从文件开头开始偏移

SEEK_CUR:从文件当前光标位置开始偏移

SEEK_END:从文件末尾开始偏移

使用函数,修改图片

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    FILE* fp = fopen("rising_freedom.bmp","r");

    fseek(fp,2,SEEK_SET);
    int bmp_size = 0;
    fread(&bmp_size,4,1,fp);
    printf("文件大小为 %d 字节\n",bmp_size);

    int w = 0,h = 0;
    fseek(fp,18,SEEK_SET);
    fread(&w,4,1,fp);
    fread(&h,4,1,fp);
    printf("图像尺寸为:%d * %d\n",w,h);

    fclose(fp);

    fp = fopen("rising_freedom.bmp","r+");

    fseek(fp,54,SEEK_SET);
    // bmp 图片默认像素格式是 bgr的
    unsigned char pix[3] = {0,0,255};
    for(int i=0;i<w;i++){
        for(int j=0;j<h;j++){
            fwrite(pix,3,1,fp);
        
        }
    }


    fclose(fp);
    return 0;
}

4.标准IO的缓存区

printf函数,缓存刷新机制

1:遇到回车自动刷新

2:缓存区满自动刷新 

3:程序结束自动刷新

4:IO切换缓存刷新

5:描述符关闭缓存刷新

6:使用 fflush函数强制刷新特定缓存区

4.1缓存区的分类

1:行缓存:printf就是行缓存

2:全缓存:FILE*指向的非终端文件,都是全缓存,全缓存刷新机制就比行缓存缺一个回车

3:无缓存:没有缓存,stderr,标准错误流是无缓存

4.2scanf的缓存区 

从键盘输入的所有数据,都会在缓存区,敲击回车,表示输入结束,这个回车也在缓存区

scanf吸收成功,就会将数据从缓存区中取走

        吸收失败则会一直留在缓存区

所以,我们要通过语句 while(getchar()!='\n') 来清理所有缓存

int a=0;
scanf("%d",&a);
while(getchar()!='\n');//用于吸收垃圾字符

4.3缓存区大小的计算

FILE 结构体里面,有2个指针

_IO_buf_base:缓存区起始地址

_IO_buf_end:缓存区尾地址

所以,只要拿缓存区尾地址 - 缓存区起始地址 = 缓存区大小了

注意:如果想要计算缓存区的大小的话,我们必须先激活一下使用这个缓存区的文件流,也就是做一下IO操作

行缓存:1024字节

全缓存:4096字节

无缓存:0字节

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	printf("hello\n");//先激活缓存区的文件流
	printf("行缓存大小为:%ld\n",stdout->_IO_buf_end - stdout->_IO_buf_base);
	
	FILE* fp = fopen("./demo11.txt","w");
	
	fputc('x',fp);
	printf("全缓存大小为:%ld\n",fp->_IO_buf_end - fp->_IO_buf_base);

	fclose(fp);

	perror("123");
	printf("无缓存大小为:%ld\n",stderr->_IO_buf_end - stderr->_IO_buf_base);
	return 0;
}

二、作业

1.使用fwrite、fread将一张随意的bmp图片,修改成德国的国旗

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
	FILE *fp=fopen("1.bmp","r");
	int w=0,h=0;
	fseek(fp,18,SEEK_SET);
	fread(&w,4,1,fp);
	fread(&h,4,1,fp);
	printf("图像尺寸为:%d * %d\n",w,h);
	fclose(fp);

	fp=fopen("1.bmp","r+");
	fseek(fp,54,SEEK_SET);
	unsigned char pix1[3]={0,0,0};
	unsigned char pix2[3]={0,0,255};
	unsigned char pix3[3]={128,255,255};
	int i=0,j=0;
	for(i=0;i<w/3;i++){
		for(j=0;j<h;j++){
			fwrite(pix3,3,1,fp);
		}
	}
	for(i=w/3;i<w/3*2;i++){
		for(j=0;j<h;j++){
			fwrite(pix2,3,1,fp);
		}
	}
	for(i=w/3*2;i<w;i++){
		for(j=0;j<h;j++){
			fwrite(pix1,3,1,fp);
		}
	}
	fclose(fp);
	return 0;
}

2.使用提供的getch函数,编写一个专门用来输入密码的函数,要求输入密码的时候,显示 * 号,输入回车的时候,密码输入结束

#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>

int getch(){
	int c=0;
	struct termios org_opts, new_opts;
	int res=0;
	res=tcgetattr(STDIN_FILENO, &org_opts);
	assert(res==0);

	new_opts = org_opts;

	new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
	tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);

	c=getchar();

	res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
	assert(res==0);
	return c;
}
int main(){
	char a[32]="0";
	int i;
	for(i=0;a[i]!='\n';i++){
		a[i]=getch();
		if(a[i]=='\n')
			break;
		printf("*");	
	}
	printf("%s",a);
	putchar(10);
}

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

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

相关文章

mysql数据库操作小寄巧

目录 json字段查询时间相关只有日期只有时间又有时间又有日期时间比较时间运算 某字段同的取最新数据&#xff08;软性的新数据覆盖旧数据查找&#xff09;sql_modeonly_full_group_by的解决办法优化思路 json字段查询 查询某个json字段&#xff08;xx&#xff09;的某个属性下…

kafka架构详解

文章目录 概述kafaka架构Kafka的设计时什么样的Zookeeper 在 Kafka 中的作用 概述 Apache Kafka 是分布式发布 - 订阅消息系统&#xff0c;在 kafka 官网上对 kafka 的定义&#xff1a;一个分布式发布 - 订阅消息传递系统。 Kafka 最初由 LinkedIn 公司开发&#xff0c;Linked…

2024.03.02 homework math

2024.03.02 homework math 1&#xff1a;路程问题&#xff0c;等量关系&#xff0c;全程的路程。 2&#xff1a;路程问题&#xff0c;等量关系&#xff0c;全程总时间

初阶数据结构:栈与队列的扩展补充

目录 1. 栈与队列练习题1.1 栈的括号匹配问题1.2 用队列来实现栈1.3 用栈来实现队列1.4 扩展&#xff1a;循环队列 1. 栈与队列练习题 1.1 栈的括号匹配问题 题目信息&#xff1a; 题目链接&#xff1a; 括号匹配问题 思路&#xff1a; 利用栈的后进先出特性来实现括号的匹配 …

opencascade c#例程解析

1.编译 将msvc.bat文件拖入vs2022的x64 native tools&#xff0c;即可 2.about.xaml <Windowxmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"x:Class"IE_WPF_WinForms…

吴恩达机器学习笔记十四 多输出的分类 多类和多标签的区别 梯度下降优化 卷积层

这里老师想讲的是multiclass classification和multilable classification的区别&#xff0c;下面是我从其他地方找到的说法: Multiclass classification 多类分类 意味着一个分类任务需要对多于两个类的数据进行分类。比如&#xff0c;对一系列的橘子&#xff0c;苹果或者梨的…

QT之液晶电子时钟

根据qt的<QLDNumber>做了一个qt液晶电子时钟. 结果 实时显示当前时间,左键可以拖动时钟在屏幕的位置,右键点击关闭显示. 实现过程 新建一个class文件,让这个文件的父类是QLCDNumber 相关功能变量定义和函数实现 .c文件代码 这里需要注意的一点是event->button是获取的…

langchain学习笔记(七)

RunnablePassthrough: Passing data through | &#x1f99c;️&#x1f517; Langchain 1、RunnablePassthrough可以在不改变或添加额外键的情况下传递输入。通常和RunnableParallel结合使用去分配数值给到字典的新键 两种方式调用RunnablePassthrough &#xff08;1&#…

【three.js】手把手带你理解制作一个3D场景 超级详细

我们主要目的是制作这样一个三维模型: 我们直接上代码,从代码中一点点解释模型是如何一步一步制作的。 // 引入three.js import * as THREE from three; /*** 创建3D场景对象Scene*/ const scene = new THREE.Scene();/*** 创建网格模型*/ //创建一个长方体几何对象Geometry…

安卓使用ExoPlayer出现膨胀类异常

1.导包 implementation com.google.android.exoplayer:exoplayer-core:2.15.1implementation com.google.android.exoplayer:exoplayer-ui:2.15.1 2.在Androidifest.xml加入权限&#xff0c;我这里加了忘了与读写权限 <uses-permission android:name"android.permissio…

ESG工具变量:最早一期、同城ESG(2009-2022年)

参照《管理评论》中席龙胜&#xff08;2022&#xff09;、《证券市场导报》中王琳璘&#xff08;2022&#xff09;的做法&#xff0c;选择企业同城市其他上市企业ESG的平均表现、企业最早一期ESG表现作为企业ESG表现的工具变量 一、数据介绍 数据名称&#xff1a;ESG工具变量—…

yolov9从头开始训练

yolov9从头开始训练 一、准备数据集 数据集相关文件存放布局如下 yolov9-datasets ├── train │ ├── images │ │ ├── image.jpg │ │ ├── │ └── labels │ ├── image.txt │ ├── ├── valid │ ├── images │ │ ├── image.jpg │ │ ├─…

项目运维方案

1. 文档介绍 2. 人员与责任 3. 运维过程内容 4. 运维资源 5. 运维服务规划保障 6. 事件处置 7. 质量改进 8. 运维边界及内容 软件开发全套资料获取&#xff1a;软件开发全套资料_数字中台建设指南-CSDN博客

CSP-201803-2-碰撞的小球

CSP-201803-2-碰撞的小球 解题思路 解题思路是通过模拟小球在数轴上的移动来计算t秒后各个小球的位置。 初始化阶段&#xff1a;首先&#xff0c;读入小球的数量 n、线段长度 L 和时间 t。然后&#xff0c;对于每个小球&#xff0c;程序读入它们的初始位置&#xff0c;并创建一…

【学习笔记】数据结构与算法05:树、层序遍历、深度优先搜索、二叉搜索树

知识出处&#xff1a;Hello算法&#xff1a;https://www.hello-algo.com/ 文章目录 2.4 树2.4.1 「二叉树 binary tree」2.4.1.1 二叉树基本操作2.4.1.2 二叉树的常见类型「完美二叉树 perfect binary tree」「完全二叉树 complete binary tree」「完满二叉树 full binary tre…

【每日刷题】数组-LC56、LC238、随想录1

1. LC56 合并区间 题目链接 Arrays.sort先让intervals里的子数组按照子数组的第一个数字值从小到大排列。开一个新数组&#xff0c;newInterval&#xff0c;存放合并好的子数组让intervals的当前子数组i的第一个数字与newInterval的当前子数组index的最后一个数字比较大小&am…

JAVA对象内存模型

Java对象内存模型 > 一个Java对象在内存中包括3个部分&#xff1a;对象头、实例数据和对齐填充 > > 数据 内存 – CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压…

【C++】核心编程--内存分区、引用

文章目录 1.内存分区模型1.1 程序运行前1.1.1 代码区1.1.2 全局区 1.2 程序运行后1.2.1 栈区1.2.2 堆区 1.3 new操作符 2. 引用2.1 给变量起别名2.2 引用做函数参数2.3 引用做函数返回值2.4 引用的本质2.25 常量引用 1.内存分区模型 C程序在执行时&#xff0c;将内存大方向划分…

第七十一天 漏洞发现-Web框架中间件联动GobyAfrogXrayAwvsVulmap

第71天 漏洞发现-Web框架中间件&联动&Goby&Afrog&Xray&Awvs&Vulmap 知识点&#xff1a; 1、Bup简单介绍&使用说明 2、Xray简单介绍&使用说明 3、AWWS简单介绍&使用说明 4、Goby简单介绍&使用说明 5、Afrog简单介绍&使用说明 6、…

Socket网络编程(五)——TCP数据发送与接收并行

目录 主要实现需求TCP 服务端收发并行重构启动main方法重构重构分离收发消息的操作重构接收消息的操作重构发送消息TCPServer调用发送消息的逻辑监听客户端链接逻辑重构Socket、流的退出与关闭 TCP 客户端收发并行重构客户端 main函数重构客户端接收消息重构客户端发送消息重构…