二进制读写才是本质

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

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. @property 的本质是什么?

    将访问.变量.访问控制进行了绑定:编译器负责自动合成. @dynamic:不会自动合成成员变量和存取方法. @property 的本质是什么?@property = ivar + getter + s ...

  2. tomcat动态查看服务器打印日志

    [root@localhost ~]# cd /usr/local/tomcat/logs [root@localhost logs]# tail -f catalina.out   FROM:htt ...

  3. caffe(2) 数据层及参数

    要运行caffe,需要先创建一个模型(model),如比较常用的Lenet,Alex等, 而一个模型由多个屋(layer)构成,每一屋又由许多参数组成.所有的参数都定义在caffe.proto这个文件 ...

  4. 用VUE做网站后台

    介绍: 这是一个用vuejs2.0和element搭建的后台管理界面. 相关技术: vuejs2.0:渐进式JavaScript框架,易用.灵活.高效,似乎任何规模的应用都适用. element:基于 ...

  5. mesg---设置当前终端的写权限

    mesg命令用于设置当前终端的写权限,即是否让其他用户向本终端发信息.将mesg设置y时,其他用户可利用write命令将信息直接显示在您的屏幕上. 语法 mesg(参数) 参数 y/n:y表示运行向当 ...

  6. 题解 HDU1565 【方格取数(1)】

    给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 题目清晰明了,这道题应该用 ...

  7. 【codeforces 821E】Okabe and El Psy Kongroo

    [题目链接]:http://codeforces.com/problemset/problem/821/E [题意] 一开始位于(0,0)的位置; 然后你每次可以往右上,右,右下3走一步; (x+1, ...

  8. Linux查看当前正在执行的进程

    Linux查看当前正在执行的进程 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps PID TTY TIME CMD 2576 pts/0 00:00:00 ...

  9. HTML <button> 标签

    HTML <button> 标签 目标 实现点击button跳转到一个新的界面 参考文档 实例 以下代码标记一个按钮: <button type="button" ...

  10. centos7 安装好python3 yum报错

    解决方法: 修改两个地方 vi /usr/bin/yum 将最前面的改为#! /usr/bin/python2 vi /usr/libexec/urlgrabber-ext-down #! /usr/ ...