lv4 嵌入式开发-4 标准IO的读写(二进制方式)

目录

[1 标准I/O -- 按对象读写](#1 标准I/O – 按对象读写)

[2 标准I/O -- 小结](#2 标准I/O – 小结)

[3 标准I/O -- 思考和练习](#3 标准I/O – 思考和练习)


文本文件和二进制的区别:

存储的格式不同:文本文件只能存储文本。除了文本都是二进制文件。

补充计算机内码概念:文本符号在计算机内部的编码(计算机内部只能存储数字0101001....,所以所有符号都要编码)

1 标准I/O -- 按对象读写

下列函数用来从流中读写若干个对象:

#include  <stdio.h>

size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr  读取内容放的位置指针
//size_t size 读取的块大小
//size_t n 读取的个数
//FILE *fp  读取的文件指针


size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
//void *ptr  写文件的内容的位置指针
//size_t size 写的块大小
//size_t n 写的个数
//FILE *fp  要写的文件指针
  • 成功返回读写的对象个数;出错时返回EOF
  • 既可以读写文本文件,也可以读写数据文件
  • 效率高

标准I/O -- fread/fwrite -- 示例

 int s[10];
  if (fread(s, sizeof(int), 10, fp) < 0) {
     perror("fread");
     return  -1;
   }
  
   struct  student {
       int  no;
       char name[8];
       float  score;
   }  s[] = {{ 1, "zhang", 97}, {2, "wang", 95}};

   fwrite(s, sizeof(struct student), 2, fp);

fread示例

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[]){
   FILE *fp;
   char *buff;   
   size_t ret;
   fp=fopen("1.txt","r");
   if(fp==NULL){
      perror("fopen");
      return 0;
   }
   
   buff=(char*)malloc(100);
   if(buff==NULL){
      return 0;

   }

   ret = fread(buff,10,1,fp);
   if(ret==-1){
       perror("fread");
       goto end;
   }
   
   printf("buf=%s\n",buff); 

end:
   free(buff);
   fclose(fp);

}

//运行结果
buf=hello worl

fwrite和fread读写二进制示例

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student{
   char name[16];
   int age;
   char sex[8];
};

int main(int argc,char *argv[]){
   FILE *fp;
   size_t ret;
   
   struct student stu;
   struct student stu2;

   fp=fopen("1.bin","w");
   if(fp==NULL){
      perror("fopen");
      return 0;
   }


   strcpy(stu.name,"zhangsan");
   stu.age = 49;
   strcpy(stu.sex,"male");
   
   ret = fwrite(&stu,sizeof(stu),1,fp);
   if(ret ==-1){
      perror("fwrite");
      goto end;

   }else{
     printf("write struct student success!\n");
   }
   fclose(fp);  //fp不关闭指针在最后,读取会乱,一定要重新打开。

   fp=fopen("1.bin","r");
   if(fp==NULL){
      perror("fopen");
      return 0;
   }
  

 
   ret = fread(&stu2,sizeof(stu),1,fp);
   if(ret ==-1){
      perror("fread");
      goto end;
   }
   
   printf("name=%s,age=%d,sex=%s\n",stu2.name,stu2.age,stu2.sex);

end:
   fclose(fp);

}

vim只能查看文本文件,查看二进制文件会显示乱码

注意事项:

文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容。

解决办法:移动指针(后面讲解)到文件头;关闭文件,重新打开

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student{
   char name[16];
   int age;
   char sex[8];
};


int main(int argc,char *argv[]){
   FILE *fp;
   size_t ret;
   
   struct student stu2;

   fp=fopen("1.bin","r");
   if(fp==NULL){
      perror("fopen");
      return 0;
   }
   ret = fread(&stu2,sizeof(stu2),1,fp);
   if(ret ==-1){
      perror("fread");
      goto end;
   }

   printf("name=%s,age=%d,sex=%s\n",stu2.name,stu2.age,stu2.sex);

 
end:
   fclose(fp);

}

2 标准I/O -- 小结

fgetc / fputc

fgets / fputs

fread / fwrite

3 标准I/O -- 思考和练习

如何利用fread / fwrite实现文件的复制?

通过命令行参数传递源文件和目标文件名

通过fread返回值判断是否读到文件末尾

cpp 复制代码
#include <stdio.h>

#define BUFFER_SIZE 4096

int main() {
    FILE *sourceFile, *targetFile;
    char buffer[BUFFER_SIZE];
    size_t bytesRead;

    // 打开源文件
    sourceFile = fopen("source.txt", "rb");
    if (sourceFile == NULL) {
        printf("无法打开源文件。\n");
        return 1;
    }

    // 打开目标文件
    targetFile = fopen("target.txt", "wb");
    if (targetFile == NULL) {
        printf("无法创建目标文件。\n");
        fclose(sourceFile);
        return 1;
    }

    // 复制文件内容
    while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, sourceFile)) > 0) {
        fwrite(buffer, 1, bytesRead, targetFile);
    }

    // 关闭文件
    fclose(sourceFile);
    fclose(targetFile);

    printf("文件复制完成。\n");

    return 0;
}

使用标准IO写2个学生的结构体数据到文件

cpp 复制代码
#include <stdio.h>
#include <string.h>

typedef struct _student
{
	char name[16];
	int age;
	char sex[8];
}student;


int main() {
	FILE *fp;
	student stu[2];
	student temp[2];
	size_t ret;


	strcpy(stu[0].name,"zhangsan");
	stu[0].age = 10;
	strcpy(stu[0].sex,"male");
	strcpy(stu[1].name,"lisi");
	stu[1].age = 11;
	strcpy(stu[1].sex,"female");

	fp = fopen("1.bin","w");
	if (fp == NULL) {
		perror("fopen");
		return 1;
	}
	
	ret = fwrite(stu,sizeof(student),2,fp);
	if(ret == -1)
	{
		perror("fwrite");
		goto end;
	}
	else
	{
		printf("Write success\n");
	}
	fclose(fp);
	
	fp = fopen("1.bin","r");
	if (fp == NULL) {
		perror("fopen");
		return 1;
	}

	ret = fread(temp, sizeof(student), 2, fp);
	if(ret == -1)
	{
		perror("fread");
		goto end;
	}
	printf("name=%s,age=%d,sex=%s\n",temp[0].name, temp[0].age, temp[0].sex);

	printf("name=%s,age=%d,sex=%s\n",temp[1].name, temp[1].age, temp[1].sex);
end:
	fclose(fp);
	return 0;
}
相关推荐
朝九晚五ฺ3 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
自由的dream3 小时前
Linux的桌面
linux
xiaozhiwise4 小时前
Makefile 之 自动化变量
linux
意疏6 小时前
【Linux 篇】Docker 的容器之海与镜像之岛:于 Linux 系统内探索容器化的奇妙航行
linux·docker
BLEACH-heiqiyihu6 小时前
RedHat7—Linux中kickstart自动安装脚本制作
linux·运维·服务器
一只爱撸猫的程序猿6 小时前
一个简单的Linux 服务器性能优化案例
linux·mysql·nginx
我的K84098 小时前
Flink整合Hudi及使用
linux·服务器·flink
1900438 小时前
linux6:常见命令介绍
linux·运维·服务器
Camellia-Echo8 小时前
【Linux从青铜到王者】Linux进程间通信(一)——待完善
linux·运维·服务器