文件结构“图”

本文详细介绍了如何通过程序读取并展示计算机文件系统的结构,包括目录与文件的层次化表示方法,以及如何实现目录与文件的有序显示。通过实例代码展示了文件系统操作的基本流程与关键函数的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 描述
在计算机上看到文件系统的结构通常很有用。Microsoft Windows上面的"explorer"程序就是这样的一个例子。但是在有图形界面之前,没有图形化的表示方法的,那时候最好的方式是把目录和文件的结构显示成一个"图"的样子,而且使用缩排的形式来表示目录的结构。比如:

这个图说明:ROOT目录包括两个文件和三个子目录。第一个子目录包含3个文件,第二个子目录是空的,第三个子目录包含一个文件。
输入
你的任务是写一个程序读取一些测试数据。每组测试数据表示一个计算机的文件结构。每组测试数据以'*'结尾,而所有合理的输入数据以'#'结尾。一组测试数据包括一些文件和目录的名字(虽然在输入中我们没有给出,但是我们总假设ROOT目录是最外层的目录)。在输入中,以']'表示一个目录的内容的结束。目录名字的第一个字母是'd',文件名字的第一个字母是'f'。文件名可能有扩展名也可能没有(比如fmyfile.dat和fmyfile)。文件和目录的名字中都不包括空格。
输出
在显示一个目录中内容的时候,先显示其中的子目录(如果有的话),然后再显示文件(如果有的话)。文件要求按照名字的字母表的顺序显示(目录不用按照名字的字母表顺序显示,只需要按照目录出现的先后显示)。对每一组测试数据,我们要先输出"DATA SET x:",这里x是测试数据的编号(从1开始)。在两组测试数据之间要输出一个空行来隔开。

你需要注意的是,我们使用一个'|'和5个空格来表示出缩排的层次。
样例输入
样例输出

提示
一个目录和它的子目录处于不同的层次
一个目录和它的里面的文件处于同一层次
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define FILEMAX 20
#define FILENAME_LENGTH 20
#define TRUE 1
#define FALSE 0
typedef int boolean;
/*
typedef struct {
	char fileName[FILENAME_LENGTH];
}FileName;
*/
typedef struct Node {
	char *file[FILEMAX]; 
	int fileIndex;
	struct Node *dir[FILEMAX];//指向孩子节点的指针数组
	int dirIndex;
	char curDir[FILENAME_LENGTH];
}Dir;
typedef Dir * ElemType;
typedef struct node {
	ElemType data;
	struct node *next;
}NNode;
typedef struct {
	NNode *head;
	int length;
}Stack;
void InitStack (Stack *stack) {
	stack->length = 0;
	stack->head = (NNode*)malloc (sizeof(NNode));
	if (!stack->head) {
		return;
	}
	stack->head->next = NULL;
}

boolean StackIsEmpty (Stack *stack) {
	if (stack->length == 0) {
		return TRUE;
	}else{
		return FALSE;
	}
}

int StackLength (Stack *stack) {
	return stack->length;
}
//入栈
void Push (Stack *stack,ElemType data) {
	NNode *newNode = (NNode*)malloc (sizeof(NNode));
	if (!newNode) {
		return;
	}
	newNode->data = data;
	newNode->next = stack->head->next;
	stack->head->next = newNode;
	stack->length++;
}
//出栈

void Pop (Stack *stack,ElemType *e) {
	NNode *f;
	if (stack->length == 0) {
		return;
	}
	*e = stack->head->next->data;
	f = stack->head->next;
	stack->head->next = f->next;
	free (f);
	stack->length--;
}
ElemType GetTop (Stack *stack) {
	if (stack->length == 0) {
		return NULL;
	}else {
		return stack->head->next->data;
	}
}
void Traverse (Stack *stack) {
	NNode *node = stack->head->next;
	while (node) {
		printf("%d ",node->data);
		node = node->next;
	}
}
//关于文件的加入,以及目录的加入的操作
void InitDir (Dir *dir,char *name) {
	dir->fileIndex = dir->dirIndex = 0;
	strcpy (dir->curDir,name);
}

void addFile (Dir *dir,char *fileName) {
	int length = strlen(fileName);
	char *ch = (char *)malloc((length + 1)*sizeof(char));
	if (!ch) {
		return;
	}
	strcpy(ch,fileName);
	dir->file[dir->fileIndex] = ch;
	dir->fileIndex++;
}

Dir* addDir (Dir *dir,char *dirName) {
	Dir *newDir = (Dir *)malloc (sizeof(Dir));
	if (!newDir) {
		exit(-1);
	}
	InitDir (newDir,dirName);//初始化新的目录
	dir->dir[dir->dirIndex] = newDir;//父目录的dir指向新建的目录
	dir->dirIndex++;
	return newDir;//返回新建的目录
}

boolean isFile (char *ch) {
	return (*ch) == 'f'?TRUE:FALSE;
}
boolean  isDir (char *ch) {
	return (*ch) == 'd'?TRUE:FALSE;
}

void sort (Dir *dir) {
	int i;
	int j;
	char *ch;
	for (i = 0;i < dir->dirIndex;i++) {
		sort(dir->dir[i]);
	}
	for (i = 0;i < dir->fileIndex - 1;i++) {
		for (j = 0;j < dir->fileIndex - i - 1;j++) {
			if (strcmp(dir->file[j],dir->file[j+1]) >0) {
				ch = dir->file[j];
				dir->file[j] = dir->file[j+1];
				dir->file[j+1] = ch;
			}
		}
	}
}
void visitFile (Dir *dir,int times) {
	int i;
	int j;
	for	(i = 0;i < times;i++) {
		printf("|     ");
	}
	printf("%s\n",dir->curDir);
	for (i = 0;i < dir->dirIndex;i++) {
		visitFile(dir->dir[i],times+1);
	}
	for (j = 0;j < dir->fileIndex;j++) {
		for	(i = 0;i < times;i++) {
			printf("|     ");
		}
		printf("%s\n",dir->file[j]);
	}
}
int main () {
	char input[20];
	int flag = 1;
	int count = 1;
	Dir *dir2;
	while (flag) {
	Dir dir;
	Stack stack;
	InitStack(&stack);
	InitDir(&dir,"ROOT");
	Push (&stack,&dir);
		while (TRUE) {
			scanf ("%s",input);
			if (strcmp (input,"*") == 0) {
				break;
			}else if (strcmp(input,"#") == 0) {
				flag = 0;
				break;
			}else if (isFile (input)) {
				addFile(GetTop(&stack),input);  
			}else if (isDir(input)) {
				dir2 = addDir(GetTop(&stack),input);
				Push (&stack,dir2);
			}else {
				Pop(&stack,&dir2);
			}
		}
			sort(&dir);
			if (flag != 0) {
				printf("DATA SET %d:\n",count);
				count++;
				visitFile (&dir,0);
				printf("\n");
			}
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值