IO进程线程day2(2023.7.26)

news2025/1/15 22:46:45

一、Xmind整理:

二、课上练习:

练习1:全缓冲

//由于编译器优化,只打开不操作,此时不会真正申请缓冲区。
fputc('a', fp);
printf("%ld\n", fp->_IO_buf_end - fp->_IO_buf_base );

刷新条件:
1.缓冲区满 (要多写一个后才能刷新前4096个
2.fflush函数,强制刷新输出流缓冲区
   #include <stdio.h>
   int fflush(FILE *stream);

3.关闭流指针   fclose
4.主函数调用return
5.调用exit函数退出程序

6.输入输出转换

7.……

功能:目前只要理解能退出程序即可
原型:

#include <stdlib.h>
void exit(int status);

参数:

int status:目前随便填一个int类型整数即可,例如 1 2 0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("./fullbuf.txt","w");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	/*由于编译器优化,只打开不操作,此时不会真正申请缓冲区。
	  fputc('a',fp);
	  printf("%ld\n",fp->_IO_buf_end - fp->_IO_buf_base);
	  */
	int i=0;
	while(i<4096+1)
	{
		fputc('a',fp);//先放到缓存区中
		i++;
	}
	while(1)
	{
	}

	fclose(fp);
	return 0;
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("./fullbuf.txt","w");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	/*由于编译器优化,只打开不操作,此时不会真正申请缓冲区。
	  fputc('a',fp);
	  printf("%ld\n",fp->_IO_buf_end - fp->_IO_buf_base);
	  */
	/*
	   int i=0;
	   while(i<4096+1)
	   {
	   fputc('a',fp);//先放到缓存区中
	   i++;
	   }

	   fputc('b',fp);
	   fflush(fp);

	   fputc('c',fp);
	   fflush(fp);

	   fputc('d',fp);
	   fflush(fp);
	   */
	fputc('e',fp);
	exit(0);

	while(1)
	{
	}

	fclose(fp);

	return 0;
}

练习2:行缓冲

printf("size=%ld\n", stdout->_IO_buf_end - stdout->_IO_buf_base);

刷新条件:
1.缓冲区满 (要多写一个后才能刷新前4096个
2.fflush函数,强制刷新输出流缓冲区
   #include <stdio.h>
   int fflush(FILE *stream);

3.关闭流指针   fclose
4.主函数调用return
5.调用exit函数退出程序

6.遇到\n字符

7.输入输出转换

功能:目前只要理解能退出程序即可
原型:

#include <stdlib.h>
void exit(int status);

参数:

int status:目前随便填一个int类型整数即可,例如 1 2 0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	char s1[20]="";
	scanf("%s",s1);//从终端获取字符串,默认使用的就是stdin流指针
	printf("s1=%s\n",s1);//将数据打印到终端,默认使用的就是stdout流指针

	char s2[20]="";
	fscanf(stdin,"%s",s2);//stdin代表从终端获取数据,此时与scanf完全等价
	fprintf(stdout,"s2=%s\n",s2);//stdout代表将数据输出到终端,此时与printf完全等价
	return 0;
}

练习3:无缓冲

无刷新条件

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	/*
	fputc('b',stderr);
	printf("size=%ld\n",stderr->_IO_buf_end - stderr->_IO_buf_base);
	*/
	fputc('d',stderr);
	perror("aaaa");
	while(1);

	return 0;
}


练习4:fputs

功能:将字符串输出到指定的文件中; fputs不会自动补充\n
原型:

#include <stdio.h>
int fputs(const char *s, FILE *stream);
int puts(const char *s);     
char str[20] = "hello";  
puts(str);

参数:

char *s:指定要输出的字符串的首地址;       
FILE *stream:流指针;

返回值:

成功,返回非负数>=0;
失败,返回EOF;

练习5:fgets

功能:从指定文件中获取字符串

1.最多获取size-1个字节,因为fgets函数在停止读取后,会在有效字符的最后一个字节补\0

2.会获取空格;会获取\n字符

3.遇到\n字符后停止读取,且会获取\n字符

原型:

#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);

参数:

char *s:存储获取到的字符串;
int size:size-1
FILE *stream:流指针;

返回值:

成功,返回存储数据空间的首地址;
失败,返回NULL;
当读取到文件结尾,且没有任何数据被读取出来,返回NULL;

在文件中有如下数据:123456789, char str[9];                 会出现什么情况:A D

                                    fgets(str, 10, fp);

                                    printf("str=%s", str);

A. 123456789              B.123456789乱码               C.12345678               D.段错误

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	//打开文件,以读的方式打开文件
	FILE* fp=fopen("./fputs.txt","r");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	char buf[20]="";
	fgets(buf,20,fp);
	printf("buf=%s\n",buf);

	fgets(buf,20,fp);
	printf("buf=%s\n",buf);

	fclose(fp);
	return 0;
}

1.使用fgets和fputs实现文件拷贝

2.使用fgets实现计算一个文件的大小

第一题:
#include <stdio.h>
#include <head.h>
int main(int argc, const char *argv[])
{
    FILE* fp_r = fopen("./01_fopen.c", "r");
    if(NULL == fp_r)
    {
        ERR_MSG("fopen");
        return -1;
    }

    FILE* fp_w = fopen("./copy.c", "w");
    if(NULL == fp_w)
    {
        ERR_MSG("fopen");
        return -1;
    }

    //读一次,写一次,直到文件读取完毕                  
    char buf[128] = "";
    while(1)
    {
        if(fgets(buf, sizeof(buf), fp_r) == NULL)
            break;
        fputs(buf, fp_w);
    }
    printf("拷贝完毕\n");

    if(fclose(fp_r) < 0)
    {
        ERR_MSG("fclose");
        return -1;
    }

    fclose(fp_w);

    return 0;
}
第二题:
#include <stdio.h>
#include <head.h>
int main(int argc, const char *argv[])
{
    FILE* fp_r = fopen("./01_fopen.c", "r");                          
    if(NULL == fp_r)
    {
        ERR_MSG("fopen");
        return -1;
    }

    //循环读取,统计字节数

    char str[20] = "";
    int count = 0;
    while(1)
    {
        if(fgets(str, sizeof(str), fp_r) == NULL)
            break;

        count+=strlen(str);     //fgets停止读取后会自动在结尾补充\0
    }
    printf("count = %d\n", count);

    if(fclose(fp_r) < 0)
    {
        ERR_MSG("fclose");
        return -1;
    }

    return 0;
}

练习6:fwrite

功能:将数据的二进制形式写入到指定的文件中;
          二进制形式--> 将数据拆分成一个一个的字节并转换成字符形式写入文件中

原型:

#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);

参数:

 void *ptr:指定要输出的数据的首地址,是void*类型,代表任意类型,所以可以输出任意类型数据;
 例如字符串char*  整型数组int*  构造类型
 size_t size:每个数据所占的字节数大小;例如:
 要输出的数据为int类型,则size==4
 要输出的数据为short类型,则size==2
 要输出的数据为char类型,则size==1
 要输出的数据为构造类型,则size==sizeof(struct 结构体名);
 size_t nmemb:指定要输出的数据个数,注意是个数,不是字节数
 总大小为size*nmemb; 具体以什么作为整体无所谓,只要输出的结果总大小相同即可;
 FILE *stream:流指针;

返回值:

成功,返回成功输出的数据个数,即nmemb;
失败, =0或者<nmemb

注意:

总大小为size*nmemb; 具体以什么作为整体无所谓,只要输出的结果总大小相同即可;

1.将整个数据作为整体,输出/输入一个数据 -->size = sizeof(数据), nmemb=1;

2.将一个字节作为整体,输出/输入sizeof个数据 -->size =1, nmemb = sizeof(数据)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("./fwrite.txt","w");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	printf("fopen success\n");
	int arr[3]={48,49,50};
	//fprintf(fp,"%d",a);
	size_t res=0;
	res=fwrite(arr,4,3,fp);
	printf("res=%ld\n",res);

	fclose(fp);

	return 0;
}

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
typedef struct a
{
	char name[18];
	int score;
}_A;
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("fwrite.txt","w");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	printf("fopen success\n");

	_A t;
	strcpy(t.name,"zhangsan");
	t.score=48;
	size_t res=fwrite(&t,sizeof(_A),1,fp);
	printf("res=%ld\n",res);

	_A brr[2]={
		{"zahngsan",65},
		{"wangwu",66}
	};

	//将数组中的单个元素作为整体,共输出两个数据,每个数据大小为sizeof(_A)
	res=fwrite(brr,sizeof(_A),2,fp);
	printf("res=%ld\n",res);

	/*
	//将brr当做整体,输出一个数据,每个数据的大小为sizeof(brr)
	res=fwrite(brr,sizeof(brr),1,fp);
	printf("res=%ld\n",res);
	*/

	/*
	int arr[3]={48,49,50};
    //fprintf(fp."%d",a);
	
	size_t res=0;
	res=fwrite(arr,4,3,fp);
	printf("res=%ld\n",res);
	*/ 

	fclose(fp);

	return 0;
}

练习7:fread

功能:将数据的二进制形式从指定文件中读取出来,转换成对应的数据

原型:

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

参数:

void *ptr:指定要将数据存储到什么位置,填对应位置的首地址。void*类型;
size_t size:每个数据所占的字节数大小;例如:
要输出的数据为int类型,则size==4
要输出的数据为short类型,则size==2
要输出的数据为char类型,则size==1
要输出的数据为构造类型,则size==sizeof(struct 结构体名);
size_t nmemb:指定要读取的数据个数,注意是个数,不是字节数
总大小为size*nmemb; 具体以什么作为整体无所谓,只要输出的结果总大小相同即可;
FILE *stream:流指针;

返回值:

成功,返回成功读取的数据个数,即nmemb;
失败或者读取到文件结尾的时候, =0或者<nmemb

练习8:fseek

功能:修改文件偏移量,到指定位置

原型:

#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);

参数:

FILE *stream:指定要修改哪个文件的偏移量;
long offset: 距离whence参数指定的偏移量。往前偏移填负数, 往后偏移填正数
int whence:
    SEEK_SET,  文件开头位置
    SEEK_CUR,  文件当前位置
    SEEK_END   文件结尾位置

返回值:

 成功,返回0;
 失败,返回-1,更新errno;
 //修改偏移量到文件开头
 int res = fseek(fp, 0, SEEK_SET);   
 将文件偏移量修改到开头:
 void rewind(FILE *stream); --->等价于 fseek(fp, 0, SEEK_SET);   

注意:

任务1:若偏移量在文件开头,能否继续往前偏移 ---> 不行

任务2:若偏移量在文件结尾,能否继续往后偏移 ---> 可以

①若是以w w+ r+的方式打开,往结尾后偏移10个字节后写入,则会从第10个字节写入数据,且前面空余部分会自动补充^@

2.若是以a a+方式打开,往后偏移10个字节后写入,从文件结尾的最后一个有效字符的后面写入。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("./fseek.txt","w+");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
	fputc('a',fp);
	fputc('b',fp);
	fputc('c',fp);
	int res=fseek(fp,0,SEEK_SET);
	printf("res=%d\n",res);

	int c=0;
	c=fgetc(fp);
	printf("c=%c %d\n",c,c);

	return 0;
}

练习9:ftell

功能:获取文件当前位置距离文件开头的偏移量

原型:

#include <stdio.h>
long ftell(FILE *stream);

返回值:

成功,返回文件当前位置距离文件开头的偏移量;
失败,返回-1,更新errno;
    
将文件偏移量修改到结尾,获取文件偏移量的值,就是文件大小。    
fseek(fp, 0, SEEK_END);
long size = ftell(fp); 

三、课后作业:

1. 使用fgets实现计算一个文件有几行

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
	FILE* fp=fopen("./fgets.txt","r");
	if(NULL==fp)
	{
		perror("fopen");
		return -1;
	}
		fseek(fp, 0, SEEK_END);
		if(ftell(fp) == 0)
			return 0;

		fseek(fp, 0, SEEK_SET);
		char buf[32] = "";
		int count = 0;
		while(1)
		{
			if(fgets(buf, sizeof(buf), fp) == NULL)
			{
				break;
			}
			if('\n' == buf[strlen(buf)-1])
				count++;
		}
		if(buf[strlen(buf)-1] != '\n')
			count++;
		printf("文件共有%d行\n",count);
	return 0;
}


2. 用fread和fwrite实现文件拷贝 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
    FILE *fp = fopen("copy1.txt","r");
    if(NULL == fp)
    {
        fprintf(stderr,"__%d__",__LINE__);
        perror("fopen");
        return -1;
    }   
    FILE *fp_w = fopen("copy2.txt","w");
    if(NULL == fp_w)
    {   
        fprintf(stderr,"__%d__",__LINE__);
        perror("fopen");
        return -1;
    }   
    char str[10];
    while(1)
    {
        memset(str,0,sizeof(str));
        if(fread(str,1,1,fp) == 0)
            break;
        fwrite(str,1,1,fp_w);
    }
    fclose(fp);
    fclose(fp_w);
    return 0;
}

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

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

相关文章

[算法很美打卡] 多维数组篇 (打卡第一天)

文章目录 顺时针打印二维数组0所在的行列清零 顺时针打印二维数组 package 每日算法学习打卡.算法打卡.七月份.七月二十六号;public class test1 {public static void main(String[] args) {int[][] matrix {{1,2},{5,6},{9,10},{13,14},};print(matrix);}static void print(i…

⛳ 面向对象面试题

面向对象面试题目录 ⛳ 面向对象面试题&#x1f69c; 一&#xff0c;成员变量&#xff0c;局部变量&#xff0c;类变量存储在内存的什么地方&#xff1f;&#x1f43e; 1.1&#xff0c;类变量&#xff08;静态成员变量&#xff09;&#x1f4dd; 1.2&#xff0c;成员变量⭐ 1.3…

代码随想录算法训练营第59天|503 42

503 我的思路是既然是循环数组 那就最多遍历两圈 其他的跟单调栈写法一模一样 class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {vector<int> result(nums.size(), -1);if (nums.size()1) return result;stack<int>…

HttpRunner自动化测试之响应中文乱码处理

响应中文乱码&#xff1a; 当调用接口&#xff0c;响应正文返回的中文是乱码时&#xff0c;一般是响应正文的编码格式不为 utf-8 导致&#xff0c;此时需要根据实际的编码格式处理 示例&#xff1a; 图1中 extract 提取title标题&#xff0c;output 输出 title 变量值&#x…

yolov8系列[五]-项目实战-yolov8模型无人机检测

yolov8系列[五]-项目实战-yolov8模型无人机检测 项目介绍项目展示功能简介代码结构如何启动 开发者模式1. 安装依赖环境2. 启动程序 源代码下载其他 项目介绍 无人机识别项目,无人机搭载nvidia jetson边缘计算板子,进行实时识别。使用yolov8算法&#xff0c;训练了识别无人机的…

leetcode 1870. Minimum Speed to Arrive on Time(准时到达的最小速度)

需要找一个speed, 使得dist[i] / speed 加起来的时间 < hour, 而且如果前一个dist[i] / speed求出来的是小数&#xff0c;必须等到下一个整数时间才计算下一个。 speed最大不会超过107. 不存在speed满足条件时返回-1. 思路&#xff1a; 如果前一个dist[i] / speed求出来的…

【万字详解】Linux进程信号||一文搞定进程信号||附测试代码

进程信号 &#x1f373;信号理解&#x1f9c8;什么是信号&#xff1f;&#x1f95e;进程信号&#x1f953;查看系统信号&#x1f969;在技术角度理解信号&#x1f357;注意 &#x1f356;信号处理&#x1f9c7;信号异步机制 &#x1f354;信号产生&#x1f35f;通过终端按键产生…

【CSS】手写 Tooltip 提示组件

文章目录 效果示例代码实现 效果示例 代码实现 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>一颗不甘坠落的流星</title><style>body {padding: 120px;}.tooltip {position: relative;display: inline-blo…

Wish入驻防封指南——附最新运营要点

近日来&#xff0c;跨境电商平台Wish有了新改革&#xff0c;为提高产品质量把控效率&#xff0c;Wish最近将入驻机制又完全开放转变为“邀请制”&#xff0c;加强了品控措施&#xff0c;也意味着商家入驻门槛变高&#xff0c;流程与之前截然不同。但对于已有跨境电商经验/没有跨…

剑指offer12 矩阵中的路径 13 机器人的运动范围 34.二叉树中和为某一值得路径

class Solution { public:bool exist(vector<vector<char>>& board, string word) {int rowboard.size(),colboard[0].size();int index0,i0,j0;if(word.size()>row*col) return 0;//vector<vector<int>> visit[row][col];//标记当前位置有没有…

ES6: 对象简写/symbol()/ Iterator/set/map/await.......

对象简写 对象名字为变量 复制对象/还有个assign方法 symbol() 这种写法用户怎么添加属性都ok 获取属性,这个方法获取symbol属性 获取属性,这个方法获取symbol和普通属性 Iterator 比较复杂,可以看视频 有迭代器的可用for..of循环 012-ES6-Iterator_哔哩哔哩_bilibili Set 它…

安防监控视频汇聚平台EasyCVR修改录像计划等待时间较长是什么原因?

安防监控视频EasyCVR视频融合汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检…

【UE5 多人联机教程】05-更改角色颜色

效果 步骤 1. 打开“BP_ThirdPersonCharacter”&#xff0c;找到角色的材质 创建材质实例 2. 在“BP_ThirdPersonCharacter”中新建一个整型变量&#xff0c;命名为“PlayerColorIndex” 勾选可编辑实例、生成时公开&#xff0c;复制选择“RepNotify” 复制选择“RepNotify”…

7.26 作业 QT

1.继续完善登录框&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;跳转到新的界面中&#xff1a; 结果图&#xff1a; second.h: #define SECOND_H#include <QWidget> #include<QDebug> //信息调试类&#xff0c;用于打印输出的 #inc…

学C的第三十天【自定义类型:结构体、枚举、联合】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第二十九天【字符串函数和内存函数的介绍&#xff08;二&#xff09;】_高高的胖子的博客-CSDN博客 1 . 结构体 &#xff08;1&#xff09;. 结构体的基础知识&#xff1a; 结构…

docker-compose yml配置、常用命令

下载完docker-compose后&#xff0c;如果想使用docker-compose命令开头&#xff0c;需要创建软连接 sudo ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/bin/docker-compose 1.docker-compose.yml文件编排 一个 docker-compose.yml 文件的顶层元素有&#xff…

线程的同步

一、互斥锁 java语言中&#xff0c;引入了对象互斥锁的概念&#xff0c;来保证共享数据操作的完整性。每个对象都对应与一个可称为“互斥锁”的标记&#xff0c;这个标记用来保证在任一时刻&#xff0c;只能有 一个线程访问该对象。关键字synchronized用来与对象的互斥锁联系。…

HTML不常用但是好用的标签

sub sup <p>这个文本包含 <sub>111</sub>文本。</p> <p>这个文本包含 <sup>上标</sup> 文本。</p>下标文本将会显示在当前文本流中字符高度的一半为基准线的下方&#xff0c;但是与当前文本流中文字的字体和字号都是一样的。…

Xilinx AXI VIP使用教程

AXI接口虽然经常使用&#xff0c;很多同学可能并不清楚Vivado里面也集成了AXI的Verification IP&#xff0c;可以当做AXI的master、pass through和slave&#xff0c;本次内容我们看下AXI VIP当作master时如何使用。 新建Vivado工程&#xff0c;并新建block design&#xff0c;命…

YOLOv7改进:CVPR 2023 | SCConv: 即插即用的空间和通道重建卷积

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点。 2.涨点效果:添加 SCConv,经过测试,有效涨点。…