Lista drzew, czyli próba zrobienia drzewa katalogów i plików

0

Witam!
W tym nowy roku postanowiłem sobie napisać funkcje do obsługi drzewa przypominającego działanie katalogów i plików w systemach operacyjnych. Niestety to co napisałem nie działa tak jak powinno.
Na samym początku zdefiniowałem sobie dwa typy danych:

/*Element listy drzew*/
struct elementListOfTree{
	struct nodeTree *folder;
	struct elementListOfTree *down, *up;
};
typedef struct elementListOfTree * listOfTree;
/*Węzeł drzewa z wieloma dziećmi*/
struct nodeTree{
	char *folder;
	listOfTree children;
};
typedef struct nodeTree * treeM;

Następnie napisałem funkcję która ma za zadanie dodać nowy "folder" do nadrzędnego katalogu:

void addNewFolder(listOfTree parent, char *new){
	listOfTree p = malloc(sizeof(listOfTree)), q;
	p->folder = new;
	p->down = NULL;
	p->folder->children = NULL;
	if (parent == NULL){
		parent = p;
		p->up = parent;
	}
	else{
		q = parent->folder->children;
		while (q->down) q = q->down;
		q->down = p;
		p->up = q;
	}
}

Kolejna funkcja miała wyszukiwać dowolny katalog w naszym drzewie katalogów i plików.

listOfTree *findFolder(listOfTree LT, char *folder){
	listOfTree p = LT, q = NULL;
	if (LT == NULL) return NULL;
	while (p->down && p->folder != folder)	p = p->down;
	if (p->folder == folder) return p;
	else{
		p = T;
		while (p->down){
			q = findFolder(p->folder->children, folder);
			if (q != NULL) break;
			p = p->down;
		}
		return q;
	}
}

No i oczywiście main:

int main(){
	listOfTree LT = NULL, a;
	char *folderName = malloc(sizeof(char));
	printf("Podaj nazwe katalogu nadrzednego: ");
	scanf("%s", folderName);

	addNewFolder(LT, folderName);

	a = findFolder(LT, folderName);
	if (a != NULL) printf("Znaleziono folder %s", folderName);
	else printf("Nie znaleziono folderu %s", folderName);
	getchar();
	getchar();
	return 0;
}

Szczerze powiedziawszy nie wiem co robię źle, ale byłbym wdzięczny gdyby ktoś mnie naprowadził na właściwy tor.

0

Pierwsze co mi się rzuciło w oczy to to

char *folderName = malloc(sizeof(char)); 

alokujesz pamięć tylko na jednego chara a nie na tablicę charów, którą jest string.

zmień na

char *folderName = malloc(sizeof(char) * 256); 

i powinno działać. Jeżeli nie masz innych błędów bo aż tak dogłębnie nie analizowałem tego co napisałeś

EDIT

następną rzeczą jest w funkcji dodającej

listOfTree p = malloc(sizeof(listOfTree)) 

wcześniej masz

typedef struct elementListOfTree * listOfTree; 

więc alokujesz pamięć na wskaźnik, a nie pamięć, która pomieści całą strukturę. Wg mnie powinno być

listOfTree p = malloc(sizeof(elementListOfTree )) 
0
zeed94 napisał(a):
	p->folder = new; // czyżby `p->folder` to nazwa ?
	p->down = NULL;
	p->folder->children = NULL; // czyżby `p->folder` to struktura ?

Masz problem ze złośliwym sabotażystą który nazwał dokładnie tak samo dwie zupełnie różne rzeczy:
elementListOfTree::folder
nodeTree::folder
W związku z czym nie masz zielonego pojęcia co robisz.
Najlepszym rozwiązaniem jest wyciąć to w pień i zacząć od nowa.

0

Więc struktury powinny wyglądać tak:

/*Element listy drzew*/
struct elementListOfTree{
	struct nodeTree * folder;
	struct elementListOfTree *down, *up;
};
typedef struct elementListOfTree * listOfTree;
/*Węzeł drzewa z wieloma dziećmi*/
struct nodeTree{
	char *folderName;
	listOfTree children;
};
typedef struct nodeTree * treeM;

A funkcja dodająca tak:

void addNewFolder(listOfTree parent, char *new){
	listOfTree p = malloc(sizeof(struct elementListOfTree)), q;;
	p->folder->folderName = new;
	p->down = NULL;
	p->folder->children = NULL;
	if (parent == NULL){
		parent = p;
		p->up = parent;
	}
	else{
		q = parent->folder->children;
		while (q->down) q = q->down;
		q->down = p;
		p->up = q;
	}
}

Lecz teraz wywala błąd w:

p->folder->folderName = new;

Co jest z tym nie tak?

0

p->folder - wskazuje na losowy obszar pamięci.
Już ci mówiłem sabotażysta zrobił tą strukturę, wywal ją, przemysł i zrób od nowa.

0
typedef struct FolderTreeStruct
  {
    char *name;
    struct FolderTreeStruct *root,*down,*up;
  } FolderTree,*FolderTreePtr;
0

Napisałem coś takiego, ale mam problem bo nie wiem czy usuwanie jest dobrze zrobione. Bo generalnie usuwać usuwa, ale nie wiem czy w pamięci nie zostają jakieś śmieci.
<code=c#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

/Definiowanie nowego typu - drzewa folderów/
typedef struct nodeTreeFolder{
unsigned int key;
char *folderName, *fileName;
struct nodeTreeFolder *root, *down, *up;
} treeFolder;

treeFolder *addNewParentFolder(treeFolder *head, char *newFolder){
treeFolder *p = malloc(sizeof(struct nodeTreeFolder)), *q;
p->folderName = newFolder;
p->key = 1;
p->down = p->root = NULL;
if (head == NULL){
p->up = head;
return p;
}
else{
q = head;
while (q->down) q = q->down;
q->down = p;
p->up = q;
return head;
}
}

treeFolder *addNewSubFolder(treeFolder *head, treeFolder *parent, char *newFolder){
treeFolder *p = malloc(sizeof(struct nodeTreeFolder)), *q;
p->folderName = newFolder;
p->key = 1;
p->down = p->root = NULL;
if (parent->root == NULL){
parent->root = p;
p->up = parent;
}
else{
q = parent->root;
while (q->down) q = q->down;
q->down = p;
p->up = q;
}
return head;
}

treeFolder *addNewFile(treeFolder *head, treeFolder *parent, char *newFile){
treeFolder *p = malloc(sizeof(struct nodeTreeFolder)), *q;
p->fileName = newFile;
p->key = 0;
p->down = NULL;
if (parent->root == NULL){
parent->root = p;
p->up = parent;
}
else{
q = parent->root;
while (q->down) q = q->down;
q->down = p;
p->up = q;
}
return head;
}

treeFolder *findFolder(treeFolder *head, char *folder){
treeFolder *p, *q = NULL;
int cmp = 0;
if (head == NULL) return NULL;
else{
p = head;
do{
cmp = strcmp(p->folderName, folder);
if (cmp == 0) return p;
else{
q = findFolder(p->root, folder);
if (q != NULL) return q;
p = p->down;
}
} while (p && cmp);
return NULL;
}
}

void printTreeFolder(treeFolder *head, int depth){
if (head != NULL){
for (int i = 0; i < depth; i++)
putchar('\t');
if (head->key == 1){
printf("/%s\n", head->folderName);
printTreeFolder(head->root, depth + 1);
}
else printf("%s\n", head->fileName);
printTreeFolder(head->down, depth);
}
}

void moveContentFolder(treeFolder *from, treeFolder *to){
treeFolder *q;
if (from->root != NULL){
if (to->root == NULL){
to->root = from->root;
from->root->up = to;
}
else{
q = to->root;
while (q->down) q = q->down;
q->down = from->root;
from->root->up = q;
}
from->root = NULL;
}
}

treeFolder *removeFolder(treeFolder *head, treeFolder *folder){
treeFolder *p;
if (head == NULL) return NULL;
if (head == folder) printf("Nie mozesz usunac katalogu domowego!\n");
else{
p = folder;
if (folder->up->root == folder){
if (folder->down == NULL) folder->up->root = NULL;
else folder->up->root = folder->down;
}
else{
if (folder->down == NULL) folder->up->root = NULL;
else folder->up->root = folder->down;
}
free(p);
}
return head;
}

int main(){
int n;
treeFolder *T = NULL, *q;
char *parentFolderName, *subFolderName, *fileName, c;

T = addNewParentFolder(T, "home");

menu:

if (T){
	printf("Twoje drzewo katalogow:\n");
	printTreeFolder(T, 0);
}

parentFolderName = malloc(sizeof(char) * 256);
subFolderName = malloc(sizeof(char) * 256);
fileName = malloc(sizeof(char) * 256);

printf("\n1.Dodaj nowy folder podrzedny\n2.Dodaj nowy plik do folderu\n3.Usuwanie folderu\n0.Zakoncz prace programu.\n");
printf("Co wybierasz? "); scanf("%d", &n);

system("cls");

switch (n){
case 0:
	return 0;
case 1:
	printf("Podaj nazwe nowego katalogu: "); scanf("%s", subFolderName);
	printf("Podaj katalog w ktorym ma sie znajdowac nowy katalog: "); scanf("%s", parentFolderName);

	q = findFolder(T, parentFolderName);
	if (q != NULL){
		printf("\nZnaleziono folder /%s\n", parentFolderName);
		T = addNewSubFolder(T, q, subFolderName);
	}
	else printf("\nNie znaleziono folderu /%s\n", parentFolderName);
	break;
case 2:
	printf("Podaj nazwe nowego pliku: "); scanf("%s", fileName);
	printf("Podaj katalog w ktorym ma sie znajdowac nowy katalog: "); scanf("%s", parentFolderName);

	q = findFolder(T, parentFolderName);
	if (q != NULL){
		printf("\nZnaleziono folder /%s\n", parentFolderName);
		T = addNewFile(T, q, fileName);
	}
	else printf("\nNie znaleziono folderu /%s\n", parentFolderName);
	break;
case 3:
	printf("Podaj nazwe katalogu, ktory chcesz usunac: "); scanf("%s", subFolderName);

	q = findFolder(T, subFolderName);
	if (q != NULL){
		printf("\nZnaleziono folder /%s\n", subFolderName);
		
	}
	else printf("\nNie znaleziono folderu /%s\n", subFolderName);

	T = removeFolder(T, q);

	break;
}

system("cls");
goto menu;


getchar();
getchar();
return 0;

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1