2017-02-14 6 views
1

Я пытался создать массив связанных списков. Массив равен 26, каждая часть соответствует букве алфавита. Пользователь вводит каталог ПК, а имя любых папок или файлов в этом каталоге затем добавляется в связанный список в массиве, основываясь на том, с какой буквы они начинаются.Массив связанных списков, добавленных из каталога

Как я пытался сделать IT->

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

Мой узел и его заявление:

struct node{ 
     char data[50]; 
     struct node *next; 
}; 

struct node* nodeArray[26]; 

Мой алфавит:

const char* basis[26] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; 

Строка сравнения функцию проверить, какой связанный список в массиве идет мое слово (сравнивается с алфавитом)

int StartsWith(const char *a, const char *b) 
{ 
    if(strncasecmp(a, b, strlen(b)) == 0) return 1; 
    return 0; 
} 

Где я добавить узел, а также, где проблема есть (Е («1») есть, чтобы остановить мой компьютер от в основном сбой):

void addNode(struct node **q,const char *d){ 
     if(((*q)->data)==NULL){ 
      *q = malloc(sizeof(struct node)); 
      strncpy((*q)->data,d,50); 
      (*q)->next = NULL; 
     } else { 
      (*q)->next = malloc(sizeof(struct node)); 
      *q = (*q)->next; 
      printf("1"); 
      addNode(q,d); 
      } 
} 

функция, которая вызывает AddNode, каталог это компьютер каталог, который уже был проверен на существование:

void returner(char* directory){ 
    int i; 
    DIR *dp; 
    struct dirent *ep; 
    char* tempD; 
    dp = opendir (directory); 
    struct node **z; 

    while ((ep = readdir(dp))){ 
       tempD = (char*)malloc(50); 
     if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")){ 

     } else { 
      strncpy(tempD, ep->d_name, 50); 
      for(i=0; i<26 ; i++){ 
       if(StartsWith(tempD, basis[i])){ 
        z = &nodeArray[i]; 
        addNode(z,tempD); 
        print(); 
       } 
      } 
     } 
     free(tempD); 
    } 
closedir (dp); 
} 

функция печати:

void print(){ 
    int i; 
    struct node *temp; 

    for(i=0 ; i < 26; i++){ 
    temp = malloc(sizeof(struct node)); 
    temp = nodeArray[i]; 
    while(temp != NULL){ 
     printf("%s\n",temp->data); 
     temp = temp->next; 
    } 
    } 
} 

Программа кажется прекрасной при добавлении первого узла в пятно на массиве, такое как «aaa.txt» «bbb.txt» «ccc.txt» «ddd.txt», но как только одна секунда пытается быть добавлена ​​как «ccd.txt» после «ccc.txt» существует, когда он держится навсегда или до сбоя ПК

ответ

1

Вы не проверяете правильное значение в своем addNode для нахождения точки вставки списка.

указателя к указателю перечисления через связанный список часто используются, чтобы идти от указателя головы до последнего next указателя в списке, каждый раз, держа адрес указанных-указатель. Когда вы достигнете одного из NULL (который будет head в случае пустого списка), вы остановитесь, и вы можете использовать указатель на указатель через разыменование для назначения вашего нового адреса узла.

Если вы хотите вставить на хвост, способ сделать это было бы что-то вроде этого:

#define DATA_MAX_LEN 50 

void addNode(struct node **q,const char *d) 
{ 
    // assumes a null-terminated linked list 
    while (*q) 
     q = &(*q)->next; 

    *q = malloc(sizeof **q); 

    // ensures truncation and termination 
    strncpy((*q)->data,d,DATA_MAX_LEN-1); 
    (*q)->data[ DATA_MAX_LEN-1] = 0; 

    // make sure we terminate the list at our new node 
    (*q)->next = NULL; 
} 

Вызванный из обновленной returner функции, как это:

void returner(char* directory) 
{ 
    DIR *dp = opendir (directory); 
    if (dp) 
    { 
     struct dirent *ep; 
     while ((ep = readdir(dp))) 
     { 
      // skip parent and self symbolic links 
      if (ep->d_name[0] == '.' && (ep->d_name[1] == 0 || (ep->d_name[1] == '.' && ep->d_name[2] == 0))) 
       continue; 

      for(int i=0; i<26 ; i++) 
      { 
       if(StartsWith(ep->d_name, basis[i])) 
        addNode(nodeArray+i, ep->d_name); 
      } 
     } 
     closedir (dp); 
    } 
} 
+0

Я вижу, спасибо это прекрасно работает! Это первый раз, когда я делаю что-то подобное в C, поэтому, я думаю, я просто зашел слишком далеко, поскольку я попытался исправить это и в конечном итоге усложнил процесс. –

+1

@SeanM вы были ближе к хорошему, чем большинство людей, как правило, впервые они пытаются работать с указателем на указатель на C. В любом случае, рад, что это помогло. Удачи. – WhozCraig

+0

@SeanM, вероятно, тоже должен был упомянуть об этом: у вас есть утечка памяти в вашей функции 'print'. В этой строке 'malloc' нет никакого бизнеса. Это не Java или C#. – WhozCraig