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;
}
相关推荐
A小辣椒15 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒19 小时前
TShark:基础知识
linux
AlfredZhao21 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言