二进制读写才是本质

二进制的读写对文件标记不敏感。

eg: 对图片进行加密与解密:

用命令的形式去执行:

//xx.exe -c src dest 加密

//xx.exe -d src dest 解密

他的参数就是argv[0-3]------使用Qt

#include<stdio.h>
#include<stdlib.h>
#include<string.h> void encode(char *buf,int n) {
for(int i = 0;i < n;i++) {
buf[i]++;
}
}
void decode(char *buf,int n) {
for(int i = 0;i < n;i++) {
buf[i]--;
}
}
int main(int argv,char *argv[]) {
if(argv != 4) {
printf("use xx.exe -d[-c] src dest\n");
exit(-1);
}
FILE *pfr = fopen(argv[2],"rb+");
if(pfr == NULL) {
exit(-1);
}
FILE *pfw = fopen(argv[3],"wb+");
if(pfw == NULL) {
fclose(pfr);
exit(-1);
}
int buf[1024];
int n;
if(strcmp(argv[1],"-c") == 0) {
while((n = fread((void *)buf,1,1024,pfr)) > 0) {
encode(buf,n);//加密函数
fwrite((void *)buf,1,n,pfw);
}
}else if(strcmpy(argc[1],"-d") == 0) {
while((n = fread((void *)buf,1,1024,pfr)) > 0) {
encode(buf,n);//加密函数
fwrite((void *)buf,1,n,pfw);
}
}else{
printf("arg error\n");
}
fclose(pfr);
fclose(pfw); return 0;
}

读写结构体的优势

结构体中的数据类型不统一,此时最适合用二进制的方式进行读写。二进制的接口可以读文本,而文本的接口不可以读二进制。

#include<stdio.h>
typedef struct student{
int num;
char name[30];
char sex;
float math;
float english;
float chinese;
}Stu; int main() {
Stu s[5] = {
{1001,"assassin",'f',89,99,100},
{1002,"wunworld",'f',99,89,79},
{1003,"intelwisd",'m',98,80,100},
{1004,"seafwg",'m',99,90,99},
{1005,"xxxx",'f',90,99,100}
};//把初始化的内容写进结构体中,读出来。
//把数据以二进制形式保存,文本原样保存
FILE * pfs = fopen("stu.data","w+");
if(pfs == NULL) {
exit(-1);
}
for(int i = 0;i < 5;i++) {
fwrite((void *)&s[i],sizeof(Stu),1,pfs);//注意&s[i],对数组取地址
}
fclose(pfs);
return 0;
}

为什么结构体采用fread/fwrite来都写?

1.结构体数据类型不统一

2.可以将二进制转化为文本,降低效率,占用多余的存储空间。

读文件:
#include<stdio.h>
typedef struct student{
int num;
char name[30];
char sex;
float math;
float english;
float chinese;
}Stu; int main() {
Stu s[5] = {
{1001,"assassin",'f',89,99,100},
{1002,"wunworld",'f',99,89,79},
{1003,"intelwisd",'m',98,80,100},
{1004,"seafwg",'m',99,90,99},
{1005,"xxxx",'f',90,99,100}
};//把初始化的内容写进结构体中,读出来。
//把数据以二进制形式保存,文本原样保存
FILE * pfw = fopen("stu.data","w+");
if(pfw == NULL) {
exit(-1);
}
Stu s;
while(fread((void *)&s,sizeof(Stu),1,pfw)) {
printf("num = %d\n",s.num);
printf("name = %s\n",s.name);
printf("sex = %c\n",s.sex);
printf("math = %.2f\n",s.math);
printf("english = %.2f\n",s.english);
printf("chinese = %.2f\n",s.chinese);
} fclose(pfw);
return 0;
}

假如以小空间来读大数据的情况,在while循环中使用循环,通过循环的小标逐渐读出数据

#include<stdio.h>
typedef struct student{
int num;
char name[30];
char sex;
float math;
float english;
float chinese;
}Stu; int main() {
Stu s[5] = {
{1001,"assassin",'f',89,99,100},
{1002,"wunworld",'f',99,89,79},
{1003,"intelwisd",'m',98,80,100},
{1004,"seafwg",'m',99,90,99},
{1005,"xxxx",'f',90,99,100}
};//把初始化的内容写进结构体中,读出来。
//把数据以二进制形式保存,文本原样保存
FILE * pfw = fopen("stu.data","w+");
if(pfw == NULL) {
exit(-1);
}
Stu s[3];//有3个,结构体有5个
while(fread((void *)&s,sizeof(Stu),1,pfw)) {
for(int i = 0;i < n;i++) {
printf("num = %d\n",s[i].num);
printf("name = %s\n",s[i].name);
printf("sex = %c\n",s[i].sex);
printf("math = %.2f\n",s[i].math);
printf("english = %.2f\n",s[i].english);
printf("chinese = %.2f\n",s[i].chinese);
}
} fclose(pfw);
return 0;
}

实践:将链表作为内存数据模型,见文件作为数据库,将终端作为交互界面。读文件生成链表,修改链表写入文件。

//1.初始化数据库,此时的数据库是文件
//2.都数据库,生成内存数据模型,链表
//3.增,查,改,删,排序
//4.更新数据库
typedef struct student
{
char name[30];
char sex;
int age;
float score;
}Stu;
typedef struct _StuNode
{
Stu data;
struct _StuNode *next;
}StuNode; void initData2File()
{
Stu s[4] =
{
{"assassin",'f',30,100},
{"wunworld",'f',27,79},
{"intelwisd",'m',25,100},
{"seafwg",'m',23,99},
{"xxxx",'f',23,100}
}
FILE *pf = fopen("stu.data","w+");
if(NULL == pf)
exit(-1);
fwrite((void *)s,sizeof(s),1,pf);
fclose(pf); return ;
} StuNode *createListFromFile(char *filePath)
{
FILE *pf = fopen(filePath,"r+");//格式写正确不然一不小心会覆盖
if(NULL == pf)
exit(-1);
StuNode *head = (StuNode *)malloc(sizeof(StuNode));
head->next = NULL; StuNode *cur = (StuNode *)malloc(sizeof(StuNode));
while(fread((void *)&cur->data,sizeof(Stu),1,pf) )
{
cur->next = head->next;
head->next = cur; cur = (StuNode *)malloc(sizeof(StuNode));
}
free(cur);
return head;
}
void traverseStuList(StuNode *head)
{
printf("name\t\t\tsex\t\tage\t\tscore\n");
head = head->next;
while(head)
{
printf("%-10s\t\t%c\t\t%d\t\t%.2f\n",head->data.name,head->data.sex,head->data.age,head->data.score);
head = head->next;
}
} void addListStuNode(StuNode *head)
{
StuNode *cur = (StuNode *)malloc(sizeof(StuNode));
printf("name:\n");
scanf("%s",cur->data.name); getchar();
printf("sex:\n");
scanf("%c",&cur->data.sex); getchar();
printf("age:\n");
scanf("%sd",&cur->data.age); getchar();
printf("score:\n");
scanf("%f",c&ur->data.score); cur->next = head->next;
head->next = cur;
} StuNode * searchListStu(StuNode *head)
{
char name[30];
printf("pls input your search name:");
scanf("%d",name);
head = head->next;
while(head)
{
if(strcmp(head-data.name,name) == 0)
break;
head - head->next;
}
return head;
}
//删除操作
void deleteListNodeStu(StuNode *head)
{
StuNode *pfind = searchListStu(head);
if(pfind == null)
{
printf("你所要删除的人不存在!\n");
return ;
}
while(head->next != pfind)
{
head = head->next;//找到前驱
}
head->next = pfind->next;
free(pfind);
return ;
}
//
int lenListStu(StuNode *head)
{
int len;
head = head->next;
while(head)
{
len++;
head = head->next;
}
return len;
}
void sortListStu(StuNode *head)
{
int len = lenListStu(head);
StuNode *prep,*p,*q;
for(int i = 0;i < len-1;i++)
{
prep = head;
p = prep->next;
q = q->next;
for(int j = 0;j < len-1-i;j++)
{
if(strcmp(p->data.name,q->data.name) > 0)
{
prep->next = q;
p->next = q->next;
q->next = p; prep = q;
q = p->next;
continue;
}
prep = prep->next;
p = p->next;
q = q->next;
}
}
}
void saveList2FileStu(StuNode *head,char *filePath)
{
FILE *pf = fopen(filePath,"w+");
if(NULL == pf)
exit(-1);
head = head->next;
while(head)
{
fwrite((void *)&head->data,sizeof(Stu),1,pf);
head =head->next;
}
fclose(pf);
}
void destoryListStu(head)
{
StuNode *t;//找个替身
while(head)
{
t = head;
head = head->next;
free(t);
}
}
int main()
{
//initdata2File();
StuNode *head = createListFromFile("stu.data");
/*
traverseStuList(head);
printf("1->add\t 2->search\t 3->delete\t4->exit\n");
int choice;
scanf("%d",&choice);
switch(choice)
{
case 1:
addListStuNode(head);
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:
printf("你输入错误!\n");
}*/ StuNode *pfind;
while(1)
{
system("cls");//系统清屏
traverseStuList(head);
printf("1->add\t 2->search\t 3->delete\t4->exit\n");
int choice;
scanf("%d",&choice);
switch(choice)
{
case 1:
addListStuNode(head);
break;
case 2:
if(pfind = searchListStu(head))
{
printf("%-10s\t\t%c\t\t%d\t\t%.2f\n",pfind->data.name,pfind->data.sex,pfind->data.age,pfind->data.score); }
else
{
printf("没有此人!\n");
}
break;
case 3:
deleteListNodeStu(head);
break;
case 4:
sortListStu(head);
break;
case 5:
saveList2FileStu(head,"stu.data");
destoryListStu(head);
return 0;
default:
printf("你输入错误!\n");
}
}
}

文件偏移

int main()
{
FILE *pf = fopen("xxx.txt","w=");
fputs("abcdefg",pf);
int n = ftell(pf);//
printf("n = %d\n",n);//n = 7,ftell(),求字节的大小
rewind(pf);//将文件重新指针向一个流的开头
n = ftell(pf);
printf("n = %d\n",n);//0 feek(pf,0,SEEK_END);//操作文件pf,从SEEK_END末尾偏移0个单位。
n = ftell(pf);
printf("n = %d\n",n);//7 feek(pf,0,SEEK_SET);//从头偏移0个
n = ftell(pf);
printf("n = %d\n",n);//0 feek(pf,1,SEEK_CUR);//从当前位置偏移一个单位
n = ftell(pf);
printf("n = %d\n",n);//0 return 0;
}

C/C++(文件操作二)的更多相关文章

  1. Node.js文件操作二

    前面的博客 Node.js文件操作一中主要是对文件的读写操作,其实还有文件这块还有一些其他操作. 一.验证文件path是否正确(系统是如下定义的) fs.exists = function(path, ...

  2. 【Directory】文件操作(初识文件操作二)

    上篇我们说了关于文件的创建删除更改可以通过File这个类来完成.对于目录的操作其实File类也可以完成创建删除等相关的操作.用法跟文件的方法大致相同. 那么下面就一起来看一下关于目录相关的用法. 一, ...

  3. 基于VC的声音文件操作(二)

    (二)VC的声音操作 操作声音文件,也就是将WAVE文件打开获取其中的声音数据,根据所需要的声音数据处理算法,进行相应的数学运算,然后将结果重新存储与WAVE格式的文件中去:可以使用CFILE类来实现 ...

  4. DAY8 文件操作(二)

    一.写 1.1写文件 # w:没有文件新建文件,有文件就清空文件 w = open('1.txt', 'w', encoding='utf-8') w.write('000\n') # 在写入大量数据 ...

  5. Java文件操作二:File文件的方法

    一.文件的判断方法 判断方法 .boolean canExecute()判断文件是否可执行 .boolean canRead()判断文件是否可读 .boolean canWrite() 判断文件是否可 ...

  6. ObjectiveC 文件操作二

    10,文件委托,以便操作文件.头部看起来像是这样. @interface MyFileManager : NSObject @property(strong)NSFileManager *fileMa ...

  7. AIR文件操作(二):使用文件对象操作文件和目录

    转载于:http://www.flashj.cn/wp/air-file-operation2.html 文件对象是啥?文件对象(File对象)是在文件系统中指向文件或目录的指针.由于安全原因,只在A ...

  8. Python 文件操作二

    readlines就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素 #coding=utf-8 f = ...

  9. iOS学习之iOS沙盒(sandbox)机制和文件操作(二)

    1.获取程序的Home目录 NSString *homeDirectory = NSHomeDirectory(); NSLog(@"path:%@", homeDirectory ...

随机推荐

  1. iview2.0 父组件访问子组件 方法

    //从父组件中访问子组件 可以给子组件定义标识 通过ref="chead" 定义  通过父组件就可以访问了

  2. caffe模型各层数据和参数可视化

    先用caffe对cifar10进行训练,将训练的结果模型进行保存,得到一个caffemodel,然后从测试图片中选出一张进行测试,并进行可视化. In [1]: #加载必要的库 import nump ...

  3. Database Exception – yii\db\Exception

    在使用Yii2框架时遇到数据库无法访问的问题: 这个是由于 通常我们在参考 教程在 MAC OS LINUX下安装 MYSQL 时,默认将PHP.ini 中的以下三项留空导致的Yii2所需的PDO组建 ...

  4. 关于thinkphp 命令行

    很多人做多年开发只懂得PHP能在浏览器下运行或者只能结合APACHE等WEB服务器运行,却不晓得,PHP也能用命令行执行,或许是由于大多人在WINDOWS平台做开发部署运行,比较少接触LINUX. T ...

  5. vue+element-ui的简洁导入导出功能

    1.前段后台管理系统中数据展示一般都是用表格,表格会涉及到导入和导出;原生js导出excel2.导入是利用element-ui的Upload 上传组件; <el-upload class=&qu ...

  6. [NOIP1999]进制位(搜索)

    P1013 进制位 题目描述 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母代表数字. 例如: + L K V E L L K V E K K V E KL V V E ...

  7. MyBatis学习总结(17)——Mybatis分页插件PageHelper

    如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件. 分页插件支持任何复杂的单表.多表分页,部分特殊情况请看重要提示. 想要使用分页插件?请看如何使用分页插件. 物理分页 该 ...

  8. Java基础学习总结(27)——7 款开源 Java 反编译工具

    今天我们要来分享一些关于Java的反编译工具,反编译听起来是一个非常高上大的技术词汇,通俗的说,反编译是一个对目标可执行程序进行逆向分析,从而得到原始代码的过程.尤其是像.NET.Java这样的运行在 ...

  9. JVM学习心得

    出处:http://blog.csdn.net/qq_16143915/article/details/51195438 一.JAVA内存管理与GC机制 Java在JVM所虚拟出的内存环境中执行,ja ...

  10. 关于jacob支持BSTR类型的经验总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 jacob是实现Java和COM之间互操作的一个开源中间件.网上大多的程序示例基本上是使用jacob调用微软的offi ...