IO进程线程2

发布于:2025-03-05 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

一、标准IO函数

  1.1 fscanf \ fprintf

        fscanf和fprintf代码示例

  1.2 fwrite| fread

        fwrite|fread的代码示例

  1.3 sprintf | snprintf

        printf\fprintf\sprintf\snprintf之间的区别?

        sprintf |snprintf 代码示例

  1.4 bzero | memset 不是IO函数

  1.5 缓冲区 

    1.5.1 全缓冲

    1.5.2 行缓冲

    1.5.3 无缓冲

1.6 标准IO中的特殊流指针

二、时间函数

  2.1 time

        time的代码示例

  2.2 localtime

        localtime代码示例

三、练习

3.1 将当前的时间写入到time. txt的文件中,如果ctrl+c退出之后,在再次执行支持断点续写

3.2 使用fwrite和fread函数实现图片的拷贝


一、标准IO函数

  1.1 fscanf \ fprintf

___________________________________
 功能:写入文件,可以写入整数,小数,字符,字符串不同的数据类型
 格式:
       #include <stdio.h>

       int printf(const char *format, ...);
       printf("hello\n");        双引号中没有占位符,则后面可以省略不写
       printf("%d",11);          双引号由一个占位符,则后面需要写一个参数
       printf("%d %f",11,3.14);  双引号里面有两个占位符,则后面需要写两个参数     
       -----------------回顾printf的使用-----------------------------
       int fprintf(FILE *stream, const char *format, ...);
参数:
    format: 格式串 由字符 汉字 占位符组成
    ...:可变参数 个数可变,类型可变,由格式串的占位符决定
    stream: 流指针
返回值:
    成功返回输出字符的个数,失败返回负数
_________________________________________
功能:从文件流指针读取不同类型的数据,当使用%d %f %s读取的数据以空格 回车表示数据的读取结束
        %c可以读取空格,回车
格式:
         #include <stdio.h>

       int scanf(const char *format, ...);
       scanf("%d",&a);
       scanf("%d %f",&a,&b);
       scanf("a");
       int fscanf(FILE *stream, const char *format, ...);
参数:
      const char *format:格式串  一般由占位符决定 字符
       ... : 可变地址列表
       stream: 流指针
 返回值:
          成功返回输入的个数
          失败返回EOF
          读取到文件结尾返回EOF   
        fscanf和fprintf代码示例

  1.2 fwrite| fread

_________________________________
功能:二进制文件的写入,把不同的数据类型转换为二进制文件,在读取时转换为单字符
    int a=100;把a以字节为单位转换为二进制,文件中以单字符的形式显示
    
格式:  #include <stdio.h>

    

       size_t fwrite(const void *ptr, size_t size, size_t nmemb,
                     FILE *stream);
参数:
    void* ptr: 写入数据的地址 (通用类型指针,可以指向任意类型的地址,但是在使用是需要类型强转)
    size: 每个数据的字节大小
    nmemb: 写入数据的个数
    stream: 流指针
返回值:
      如果成功则返回项目条的个数nmemb这个参数
      如果size==1, 则返回是元素的总字节数
      如果遇到文件结尾或失败,则返回小于nmemb的值或者是0 
——————————————————————————————————————
eg:
     int a=100;
      fwrite(&a,sizeof(a),1,fp); ---->返回  1
      等价于  fwrite(&a,1,sizeof(a),fp);--->返回4
      
      int arr[]={1,2,3,4};
      fwrite(arr,sizeof(int),3,fp) --->把数组全部写入 1 2 3
      fwrite(arr,sizeof(int),3,fp) ---》不建议使用,重复写入第一次写入3个,剩一个在写入3个
         写入数据有问题,建议一次一个,后面一般不会出问题
———————————————————————————————————————————
功能:读取二进制文件
格式:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数:
    void* ptr: 存储读取的数据 (通用类型指针,可以指向任意类型的地址,但是在使用是需要类型强转)
    size: 每个数据的字节大小
    nmemb: 写入数据的个数
    stream: 流指针
返回值:
      如果成功则返回项目条的个数nmemb这个参数
      如果size==1, 则返回是元素的总字节数
      如果遇到文件结尾或失败,则返回小于nmemb的值或者是0 
      读取失败不清楚是因为什么原因,那么可以调用一下两个函数进行判断
      如果feof函数为真,则读取到文件结尾
      如果ferror函数为真,则读取失败
      int feof(FILE *stream);

      int ferror(FILE *stream);
        fwrite|fread的代码示例

  1.3 sprintf | snprintf

        当调用fwrite函数时,把一个整数转换为二进制,在把二进制的字符形式写入到文件中,展示给程序员(看不懂)

        把整数,小数转换为字符串,把字符串通过二进制的形式写入到文件中,那么在文件中显示的结果就是本身

        sprintf|snprintf 都是把整数,小数等转换为字符串

功能:把不同的数据类型那个转换为字符串存到str指针指向的内存中,可能数组越界
格式:
  int sprintf(char *str, const char *format, ...);
参数:
    format: 格式串 由字符 汉字 占位符组成
    ...:可变参数 个数可变,类型可变,由格式串的占位符决定
    str: 存储格式串中的内容
返回值:
      成功返回输出字符的个数,失败返回负数
        
    int a=100;
    char str[128]={0};
    sprintf(str,"%d",a);   ---->str="100"
———————————————————————————————————————————————————
功能:把不同的数据类型那个转换为字符串存到str指针指向的内存中,解决数据越界
格式:int snprintf(char *str, size_t size, const char *format, ...);
 参数:
       format: 格式串 由字符 汉字 占位符组成
    ...:可变参数 个数可变,类型可变,由格式串的占位符决定
    str: 存储格式串中的内容
    size:  str指针指向的内存字节大小   sizeof(str)
返回值:
      成功返回输出字符的个数,失败返回负数     
        printf\fprintf\sprintf\snprintf之间的区别?
1.printf: 格式串输出,会在当前终端打印输出结果
2.fprintf:文件的写入,可以写入不同的数据类型(int,float char char*)
3.sprintf: 把整数,小数等转换为字符串
4.snprintf: 类似sprintf,可以指定字符串的长度,防止在转换时穿线越界
        sprintf |snprintf 代码示例

  1.4 bzero | memset 不是IO函数

功能:清0
    #include <strings.h>

       void bzero(void *s, size_t n);
参数:
    void *s: 清0的变量地址
    n:  字节大小
eg:
        int arr[]={1,2,3};
        bzero(arr,sizeof(arr));
_____________________________________
功能:实现内存清0 -1  字符
格式:
 #include <string.h>

 void *memset(void *s, int c, size_t n);
参数:
    void*s: 清0的地址
    c:   清的值 可以0  -1  任意字符
    n: 总字节大小   sizeof()
返回值:
    返回s的地址


eg: 
    int arr={1,2,3};
    memset(arr,0,sizeof(arr));  清0
    memset(arr,-1,sizeof(arr));  请-1
    
    char str[]="hello";
    memset(str,'c',sizeof(str));  清字符c

  1.5 缓冲区 

        只有标准IO函数存在缓冲区

    1.5.1 全缓冲

        全缓冲的对象:使用fopen函数打开文件后,返回一个流指针,此时这就是全缓冲

全缓冲的大小:4096字节----->4k

全缓冲的刷新机制:

        1.缓冲区满

int main(int argc, const char *argv[])
{
    FILE* fp=fopen("./one.txt","w");
    if(NULL==fp)
    {
        PRINT_ERROR("fopen error");
    }                                   

    //全缓冲的大小
    for(int i=0;i<4097;i++)
    {
        if( fputc('a',fp)==EOF)
        {
            printf("fputc error\n");
            return -1;
        }

    }
    while(1);

    fclose(fp);
    return 0;
}

        2. 使用fflush函数进行刷新 常用

功能:刷新缓冲区
格式:
 #include <stdio.h>

 int fflush(FILE *stream);
参数: stream:流指针
返回值:
    成功返回0,失败返回EOF 跟新errno

        3.使用fclose函数关闭流指针

        4.使用return关闭

        5.使用exit退出实现刷新

功能:退出进程,刷新缓冲区
 格式:#include <stdlib.h>

 void exit(int status);
 参数:
     status: 退出状态值   写0就行

eg:exit(0)
    1.5.2 行缓冲

        行缓冲的对象:特殊流指针stdin stdout

        行缓冲的大小:1024字节-----》1K

int main(int argc, const char *argv[])
{

    fprintf(stdout,"hello");

    //行换从的大小
    int len=stdout->_IO_buf_end-stdout->_IO_buf_base;
    printf("len=%d\n",len);


    int a;
    fscanf(stdin,"%d",&a);
    len=stdin->_IO_buf_end-stdin->_IO_buf_base;
    printf("len=%d\n",len);
                                                        
    return 0;
}

        行缓冲的刷新机制:

        1.行缓冲区满

        2.使用fflush函数进行刷新 常用

        3.使用fclose函数关闭流指针

        4.使用return关闭

        5.使用exit退出实现刷新

        6.\n可以刷新行缓冲

        7.读写转换

    1.5.3 无缓冲

        无缓冲的对象:stderr

        大小:0

        无缓冲一般用于打印错误信息,防止错误信息存在缓冲区未被刷新的情况

        stderr的时效性比stdou强,但是速度慢,因为没有缓冲区

1.6 标准IO中的特殊流指针

当main函数启动之前,会自动创建三个特殊的流指针stdin stdout stderr

流指针

解释

等价关系

文件描述符

stdin

标准输入流指针,实现输入

gets--->fgets( str,sizeof(str),stdin)

getchar-->fgetc('a',stdin)

scanf--->fscanf(stdin,"%d",&a)

0

stdout

标准输出流指针,实现输出

puts --->fputs(str,stdout)

putchar-->fputc

printf-->fprintf

1

stderr

标准错误输出流指针

perror-->fprintf(stderr,"error");

2

二、时间函数

  2.1 time

功能:获取此时到1970-1-1 0:0:0  的时间差,单位秒
  #include <time.h>

 time_t time(time_t *tloc);
参数:
    参数:tloc 该指针指向的存储存储秒数差,如果是NULL,则不获取
返回值:
    成功返回秒数差,失败返回-1

        time的代码示例

  2.2 localtime

功能:获取此时到1970-1-1 0:0:0  的秒数差,转换为年月日时分秒
格式  #include <time.h>


  struct tm *localtime(const time_t *timep);
参数:
    timep: time函数获取的秒数差
返回值: 成功返回一个struct tm的指针,失败返回NULL,跟新错误码

        struct tm *    时间结构体 
  struct tm {
      int tm_sec;    /* Seconds (0-60) */   秒
      int tm_min;    /* Minutes (0-59) */    分
      int tm_hour;   /* Hours (0-23) */     时
      int tm_mday;   /* Day of the month (1-31) */  天
      int tm_mon;    /* Month (0-11) */     月+1
      int tm_year;   /* Year - 1900 */      年+1900
      int tm_wday;   /* Day of the week (0-6, Sunday = 0) */  星期
      int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */ 一年的第几天
      int tm_isdst;  /* Daylight saving time */     夏令时
  };

        localtime代码示例

三、练习

3.1 将当前的时间写入到time. txt的文件中,如果ctrl+c退出之后,在再次执行支持断点续写

1.2022-04-26 19:10:20

2.2022-04-26 19:10:21

3.2022-04-26 19:10:22

//按下ctrl+c停止,再次执行程序

4.2022-04-26 20:00:00

5.2022-04-26 20:00:01

#include "head.h"
int main(int argc, const char *argv[])
{
	FILE *fp=fopen("./time.txt","a+");
	if(NULL==fp)
		PRINTF_ERROR("fopen error");
	int count=0;
	rewind(fp);
	while(1)
	{
		char buf[128];
		if(fgets(buf,sizeof(buf),fp)!=NULL)
			count++;
		else
			break;
	}
	while(1)
	{		
		fseek(fp,0,SEEK_END);
		count++;
		time_t sec;
		time(&sec);
		struct tm *t=localtime(&sec);
		if(NULL==t)
			PRINTF_ERROR("localtime error");
		fprintf(fp,"%d.%04d-%02d-%02d %02d:%02d:%02d\n",count,t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
		printf("%d.%04d-%02d-%02d %02d:%02d:%02d\n",count,t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
		sleep(1);
	}
	fclose(fp);
	return 0;
}

3.2 使用fwrite和fread函数实现图片的拷贝

prt sc ---截图

eog 文件名 ----》打开文件

#include "head.h"
int main(int argc, const char *argv[])
{
	FILE *fp=fopen("./02_截图.png","r");
	if(NULL==fp)
		PRINTF_ERROR("fopen error");
	FILE *fp2=fopen("./cp_02_截图.png","w+");
	if(NULL==fp2)
		PRINTF_ERROR("fopen error");
	fseek(fp,0,SEEK_END);
	int size=ftell(fp);
	char str[size+1];
	rewind(fp);
	fread(str,size+1,1,fp);
	fwrite(str,size+1,1,fp2);
	fclose(fp);
	fclose(fp2);
	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到