首页 > 其他分享 >C语言实现最简单的2048存档读档功能(获取当前路径和文件IO)

C语言实现最简单的2048存档读档功能(获取当前路径和文件IO)

时间:2022-11-25 22:13:33浏览次数:44  
标签:puts 存档 getcwd 2048 C语言 char IO path NULL

简介

最近大一的学弟开始布置C语言的大作业了,于是在此提供一种比较简单的2048存档读档功能的实现

1 获取当前目录及存档文件

记得自己大一的时候在这里研究了很久,在这里提供C语言的实现思路
首先是用到的函数介绍:

getcwd()

按住Ctrl后点击getcwd可以知道getcwd接受两个变量:一个char*,用于以字符串形式保存绝对地,另一个变量是第一个变量字符串的大小,以防止出现路径长度大于字符串长度的情况。返回值就是当前路径的字符串形式。以下是常见用法的demo

#include<unistd.h>//记得getcwd是在unistd.h头文件中的,使用时请记得包含相关头文件

char _paTh[2048];//用于储存当前路径
getcwd(_paTh,sizeof(_paTh));//将当前路径赋值给noWPos

对于这种用法有一个显而易见的问题:我们无法判断当前路径的长度,因此只能尽可能开大这个字符串的空间。但是另一方面,开过大的字符串难免会造成内存空间的浪费。
还记得之前说的getcwd的返回值是字符串首地址吗?在getcwd函数运行过程中,函数会自动申请空间来储存这个字符串。因此我们可以不给字符串申请空间来使getcwd自动申请内存空间,并将返回值首地址赋给用于储存的char*。样例如下:

char *path = NULL;
path = getcwd(NULL,0);
puts(path);//甚至可以直接puts(path)

fopen()

在获取到当前路径后,我们就可以用fopen函数打开存档文件,在此之前先复习下fopen的基本用法
fopen接受两个char*变量,第一个记录文件的路径,第二个表示文件的读取模式,返回值为File*(文件指针)
对于第一个变量,我们需要传入完整的文件路径,这就需要我们将文件名和路径两个字符串拼接在一起(不会的自行复习strcat()函数)

#include<stdio.h>
#include<string.h>//包含strcat()
#include<unistd.h>//包含getcwd()
  char *path = NULL;//新建char* 空指针
  path = getcwd(NULL,0);//保存绝对路径
  strcat(path,"\\data.txt");//将存档文件名和路径拼接,由于转义字符的原因此处反斜杠要写两个
  puts(path);//输出完整文件名测试

获取到文件名之后,按照fopen的访问规则打开文件即可,常用的访问规则有:

"r+"	打开一个用于更新的文件,可读取也可写入。该文件必须存在。
"w+"	创建一个用于读写的空文件。

对我们要实现的功能进行分析,读档自然是使用"r+"模式,读取已有的存档,如不存在返回失败。
对于存档,覆盖已有存档或保存新存档,则使用"w+"模式
综上所述,对于存档打开过程,可以写出如下代码:

void save(){
	FILE* f;
	char *path = NULL;
	path = getcwd(NULL,0);
	puts(path);
	strcat(path,"\\data");
	puts(path);
	f=fopen(path,"w+");
} 

void lord(){
	FILE* fp;
	char *path = NULL;
	path = getcwd(NULL,0);
	puts(path);
	strcat(path,"\\data");
	puts(path);
	fp=fopen(path,"r+");
	if(fp==NULL){printf("不存在存档\n");return;}
}

存档格式

在讨论存档格式前,我们先参考下常见ACM题目对于图论存图的用例形式
image
由此可知,我们可以使用邻接矩阵的方式,在文件和内存之间相互转化

设计文件格式如下:

第一行,给出一个整数n,表示方阵的边长(如不是方阵则设为n m两个整数分别表示长和宽)
以下n行,每行给出n个整数,表示当前位置的值

文件流的输入输出:fscanf()和fprintf()

由函数名就不难看出,这两个函数与scanf()printf()非常相似,事实上这两个函数在使用上只要在传参的最前面加上FILE* fp即可
例如从fp指向的文件读入一个整数到n:

fscnaf(fp,"%d",&n);//对比scanf("%d",&n)

再例如向fp指向的文件输出一个整数n

fprintf(fp,"%d",n)//对比printf("%d",n)

综上我们可以写出完整的存档读档代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int** map;//存图数组 
int n;//图的大小 

void save(){
	FILE* f;
	char *path = NULL;
	path = getcwd(NULL,0);
	puts(path);
	strcat(path,"\\data");
	puts(path);//输出完整的地址用于测试 
	f=fopen(path,"w+");//打开文件 
	fprintf(f,"%d\n",n);//输出尺寸 
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++)
			fprintf(f,"%d ",map[i][j]);//输出图 
		fprintf(f,"\n");
	}
	return;
} 

void lord(){
	FILE* fp;
	char *path = NULL;
	path = getcwd(NULL,0);
	puts(path);
	strcat(path,"\\data");
	puts(path);//输出完整地址用于测试 
	fp=fopen(path,"r+");//打开文件 
	if(fp==NULL){printf("不存在存档\n");return;}//特判:如不存在改存档直接报错 
	fscanf(fp," %d",&n);//读入图的大小 
	map=(int**)malloc(n*sizeof(int*));//申请空间 
	for(int i=0;i<n;i++)
		map[i]=(int**)malloc(n*sizeof(int));
	//申请空间完成	
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			fscanf(fp,"%d ",&map[i][j]);//依次读入图的元素 
	return;
}

void get_data(){//简单的获取存档函数 
	printf("请输入你要 1.存档还是 2.读档\n");
	int c;scanf("%d",&c);
	if(c==1)save();
	else lord();
}

void tsave(){//测试存档功能的函数,生成一个图并存入data文件 
	scanf("%d",&n);
	map=(int**)malloc(n*sizeof(int*));
	for(int i=0;i<n;i++)map[i]=(int**)malloc(n*sizeof(int));
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			scanf("%d",&map[i][j]);		
} 
void tlord(){//测试读档功能的函数,在控制台输出从data文件读区的存档 
    for(int i=0;i<n;i++){
		for(int j=0;j<n;j++)
			printf("%d ",map[i][j]);
		printf("\n");
	}	
} 

int main(){
//	tsave();
	get_data();
//	tlord();
    return 0;
}

测试读档功能:
image

测试存档功能:
image

标签:puts,存档,getcwd,2048,C语言,char,IO,path,NULL
From: https://www.cnblogs.com/Chitoge/p/16923935.html

相关文章