嵌入式学习第十六天--stdio(二)
- 游戏开发
- 2025-09-03 08:36:01

文件打开 open函数
#include <fcntl.h> int open(const char *pathname,int flags); int open(const char *pathname,int flags,mode_t mode); 功能: 打开或创建文件 参数: @pathname //打开的文件名 @flags //操作的标志 //必选 O_RDONLY //只读 O_WRONLY //只写 O_RDWR //读写 //附加 O_APPEND //追加 O_CREAT //文件不存在 创建 O_TRUNC //文件存在 截短为0 @mode 一般不用 当flags中使用了 O_CREAT 时,需要指定 mode mode 0777 0666 0444 返回值: 成功 文件描述符 失败 -1 && errno会被设置 fopen open r O_RDONLY r+ O_RDWR
w O_WRONLY|O_CREAT|O_TRUNC w+ O_RDWR|O_CREAT|O_TRUNC
a O_WRONLY|O_APPEND|O_CREAT a+ O_RDWR |O_APPEND|O_CREAT
FILE * fopen(const char *pathname,const char *mode) { ... if (strcmp("r",mode)) open(pathname,O_RDONLY); }
文件创建好后的权限:a.指定的mode b.umask (掩码) //二进制位 --- 遮住
最终文件的权限 = ~umask & mode 0 7 7 7 111 111 111 mode 0 000 000 010 111 111 101 ~umask ------------ 111 111 101 7 7 5
库函数 和 系统调用 close 关闭:
int close(int fd); 功能: 关闭文件描述符 以便 再次使用 参数: @fd 要关闭的文件描述符 返回值: 成功 0 失败 -1
文件描述符:1.非负整型数值 2.分配原则 最小未使用 3.范围 0~1023
ssize_t read(int fd, void *buf, size_t count);#include <unistd.h> 功能: 从fd中读数据 ,存到 buf中 参数: @fd 要读取的文件 @buf 存放读取到的数据的 内存空间 @count 一次要读取的数量(字节) 返回值: 成功 表示成功读到的字节数 失败 -1 && errno
ssize_t write(int fd,const void *buf, size_t count);#include <unistd.h> 功能: 把buf中 写到fd中 参数: @fd 要写入的文件 @buf 存放数据的 内存空间 @count 一次要写入的数量(字节) 返回值: 成功 表示成功写入的字节数 失败 -1 && errno
缓存的设计缓存 设计的目的提高效率 本质上来说 ---缓存其实就是一块内存空间
行缓冲:1k, terminal,主要用于人机交互stdout 缓存区满或者遇到\n刷新 1024 行缓存多是关于终端的一些操作 1.遇到\n刷新 2.缓存区满刷新 3.程序结束刷新 4.fflush刷新 fflush(stdout);
全缓冲4k,主要用于文件的读写 缓存区满刷新缓存区 4096 对普通文件进行标准IO操作,建立 的缓存一般为全缓存 刷新条件: 1.缓存区满刷新 2.程序结束刷新 3.fflush来刷新 fflush(fp);
无缓冲0k 主要用于出错处理信息的输出 stderr 不对数据缓存直接刷新 printf();==>>stdout fprintf(strerr,"fopen error %s",filename); 界面交互 出错处理 使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。 缓冲区的大小是可以设置
linux下缓存设计: 交互 --- 行缓存 文件 --- 全缓存 出错 --- 不缓存
./a.out < main.c //< 表示输入重定向 ./a.out > main.c //> 表示输出重定向
fread/fwrite //二进制读写函数 按对象读写
#include <stdio.h> size_t fread( void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 功能: 二进制流的读/写 参数: @ptr 表示存放数据的空间的地址 @size 要操作的单个元素(对象)的大小 @nmemb 要操作的元素(对象)的个数 @stream 要操作的文件 返回值: 成功 返回的是 成功操作到的对象的个数 失败 0 到达文件结尾 返回 0 应用: 主要 应用在 文件中 有固定格式的 场景 eg: 将3个学生的信息,写到文件中 之后,从文件中读出学生信息,打印
#include<stdio.h> struct student { char name[10]; int sno; float score; }; int main(int argc, const char *argv[]) { FILE* fp = fopen(argv[1],"r+"); if(argc!=2) { printf("Usage:%s<filename>",argv[0]); return -1; } if(fp==NULL) { perror("fail open"); return -1; } struct student s[3]={"tom",110,99.7, "henry",111,99.8, "jery",112,99.2}; fwrite(s,sizeof(struct student ),3,fp); rewind(fp); struct student s1[3]; fread(s1,sizeof(struct student ),3,fp); int i=0; for(i=0;i<3;i++) { printf("%s\n",s[i].name); printf("%d\n",s[i].sno); printf("%f\n",s[i].score); } fclose(fp); return 0; } 文件偏移量:rewind
int fseek(FILE* stream,long offset,int whence);功能: 定位文件 参数: @stream 表示要操作文件 @offset 表示文件偏移量 @whence 定位的参考点 SEEK_SET //相对于文件开头的 offset >=0 SEEK_CUR //相对于当前位置 offset>=0 offset<0 //不能超过这个文件开头 SEEK_END //相对于文件末尾 offset < 0 //不能超过这个文件开头 offset >= 0 //可以 --- 创建 空洞 文件 返回值: 成功 0 失败 -1 fseek(fp,100,SEEK_SET);// fseek(fp,0,SEEK_SET);//定位到开头 fseek(fp,0,SEEK_END);//定位到末尾 创建空洞文件: 1.做偏移 2.写操作
#include<stdio.h> int main(int argc, const char *argv[]) { if(argc != 3) { printf("Usage:%s<filename><filename>\n",argv[0]); return -1; } FILE *fp1=fopen(argv[1],"r+"); fseek(fp1,0,SEEK_END); long len = ftell(fp1); fseek(fp1,0,SEEK_SET); FILE *fp_h = fopen(argv[2],"w+"); if(fseek(fp_h,len-1,SEEK_END)!=0) { perror("fseek fail"); return -1; } fputc('\0',fp_h); fseek(fp_h,0,SEEK_SET); char buf[100]; //char buf[len]; //ret=fread(buf,sizeof(buf),1,fp1); int ret; while(ret=fread(buf,sizeof(char),sizeof(buf),fp1)) { fwrite(buf,sizeof(char),ret,fp_h); } fclose(fp1); fclose(fp_h); return 0; }//空洞文件中的数据 ,都是0
long ftell(FILE*stream);功能: 获得当前文件的偏移量 void rewind(FILE*stream); 功能: 将文件偏移量设置到文件开头 获得某个文件的大小: 1. fseek(fp,0,SEEK_END);//定位到末尾 2. long len =ftell(fp); 练习: cp
#include<stdio.h> int main(int argc, const char *argv[]) { if(argc!=3) { printf("Usage:%s<filename><filename>",argv[0]); } FILE* fp = fopen(argv[1],"r+"); FILE* fp1 = fopen(argv[2],"r+"); char buf[1000]; int ret; while(ret= fread(buf,sizeof(char),1000,fp)) { fwrite(buf,sizeof(char),ret,fp1); } fclose(fp); fclose(fp1); return 0; }eg: 1.统计文件中英文字符出现的次数
#include<stdio.h> #include<fcntl.h> #include<unistd.h> int main(int argc, const char *argv[]) { if(argc!=2) { printf("Usage:%s<filename>",argv[0]); return -1; } if(argv[1]==NULL) { perror("fail open"); return -1; } int fd = open(argv[1],O_RDONLY); unsigned char ch; int cnt[26]={0}; while(read(fd,&ch,1)!=0) { if(ch>='a'&&ch<='z') { cnt[ch-'a']++; } else if(ch>='A'&&ch<='Z') { cnt[ch-'A']++; } } int i; for(i=0;i<26;i++) { printf("%c:%d\n",i+'a',cnt[i]); } return 0; }2. bmp图片: [54头信息] [图像信息] //bmp图像信息 --- 原始图像
#include<stdio.h> //-/a.out 0.bmp 2.bmp 3.bmp int main(int argc, const char *argv[]) { if(argc != 4) { printf("usage: %s <src0.bnp> <src2.bnp> <dest.bnp>\n",argv[0]); return -1; } FILE *fp1 = fopen(argv[1],"r"); FILE *fp2 = fopen(argv[2],"r"); FILE *fp3 = fopen(argv[3],"w"); if (fp1 == NULL || fp2 == NULL || fp3 == NULL) { perror("fopen fail"); return -1; } unsigned char head1[54];// unsigned char head2[54];// unsigned char body1[600*800*3];// unsigned char body2[600*800*3];// fread(head1, sizeof(unsigned char),54,fp1); fread(body1,sizeof(unsigned char),600*800*3,fp1); fread(head2,sizeof(unsigned char),54,fp2); fread(body2,sizeof(unsigned char),600*800*3,fp2); int i=0; for(i=0;i<600*800*3;i++) { if (!(body1[i] == 255&&body1[i+1]==255&&body1[i+2]==255)) { body2[i] =body1[i]; body2[i+1] = body1[i+1]; body2[i+2] =body1[i+2]; } } fwrite(head2,sizeof(char),54,fp3); fwrite(body2,sizeof(char),600*800*3,fp3); fclose(fp1); fclose(fp2); fclose(fp3); return 0; }运行结果:
1.bmp
2.bmp
t.bmp
嵌入式学习第十六天--stdio(二)由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“嵌入式学习第十六天--stdio(二)”
上一篇
VSCode实用快捷键
下一篇
Java高频面试之SE-22