粽锁粥汁,存档码是游戏中必不可少的存在。如果没有了它,也许打王者时花了一天时间升的段位在下次登陆时全部清空,又或是氪金买的皮肤又不能用了。今天,小编就教大家如何用传统C语言写一个安全性极高的游戏存档(普通玩家无法访问或修改)
首先,了解一下C语言文件读写的基本函数和格式(头文件为stdio.h)
int fprintf( FILE* stream, const char* format, [argument...]);
int fscanf( FILE* stream, const char* format, [argument...]);
这里的fprintf()函数用于向第一个参数stream中写入数据,除了第一个参数,其用法和printf()一毛一样;同理,fscanf()函数则是从stream中读取数据,与scanf()函数一样。
但是,第一个参数为FILE*类型,也就是文件指针,需要重新定义:
FILE* fp = fopen(文件名,读写模式)
fopen函数返回一个FILE*类型数值,我们将它存进fp里方便后续操作。
关于读写模式,这里先讲几种:
r:只读(如fp不存在(为NULL)则不读)
w:重写(如fp不存在则新建,存在则删除文件所有内容重写)
a:追加(如fp不存在则新建,存在则往文件最后追加内容)
这里我们用r和w就好,因为每次都会删除文件内容然后更新。
我们通常都会选择用txt文件读写来存档:
struct Player{
......
}player;
void save()
{
FILE* fp = fopen("存档.txt","w");
fprintf(fp,"%d %d %d",player.hp,player.gold,player.lvl);
fclose(fp);
}
这里,我们定义了一个名为Player的结构体,包含血量、金币、等级等。在save函数中,我们创建(或重写)了一个名为存档的txt文件,再通过第7行的fprintf函数将它们写入文件中,最后用fclose()函数关闭文件。
但是,这样有一个很明显的缺点:安全性极低,用户只要找到文件,就可以随意进行修改。于是,我们便有了用二进制文件的想法:
void save()
{
FILE* fp = fopen("存档.dat","w");
fprintf(fp,"%d %d %d",player.hp,player.gold,player.lvl);
fclose(fp);
}
这段代码看似可行,实际上却不能成功,读取时是一堆乱码。因为在没有定义的情况下,系统默认使用文本文件的读写模式对文件进行操作。于是,在r、w和a三种基本操作模式上,又引申出了rb、wb和ab,(b:binary二进制缩写)像计算机表明 “ 我要做二进制文件的操作,别用你默认的文本文件了 ”的意思。所以,第四行应改为:
FILE* fp = fopen("存档.dat","wb");
同样的,我们再写读档时就好写了许多:
void read()
{
FILE* fp = fopen("存档.dat","rb");
if(fp != NULL){
fscanf(fp,"%d%d%d",&player.hp,&player.gold,&player.lvl);
fclose(fp);
}else{
printf("文件不存在!\n");
exit(1);
}
}
唯一不同的就是,在第四行我们多作了一个判断,避免我们写代码时先于save()函数调用read()函数,实际编写代码时,可以以此判断是不是新玩家初入游戏,决定是否显示新手教程等等,总之很实用就对了。
最后,制作不易,我又莫得粉丝,莫得赞,你懂得
拜拜~