【问题标题】:Array of linked lists added to from directory添加到目录的链表数组
【发布时间】:2017-02-14 05:31:05
【问题描述】:

我一直在尝试创建一个链表数组。该数组的大小为 26,每个部分对应于字母表中的一个字母。用户输入 PC 的目录,然后该目录中的任何文件夹或文件的名称将根据它们的开头字母添加到数组中的链表中。

我是怎么做到的->

#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;
}

我在哪里添加节点以及问题出在哪里(printf("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的函数,directory是已经检查存在的计算机目录:

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”,但是尝试添加第二个节点就像“ccc.txt”之后的“ccd.txt”一样,当它永远运行或直到电脑崩溃时,它就存在

【问题讨论】:

    标签: c arrays linked-list dirent.h


    【解决方案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);
        }
    }
    

    【讨论】:

    • 我明白了,非常感谢,这很好用!这是第一次在 C 语言中做这样的事情,所以我认为我在尝试修复它时太过分了,最终使它在过程中变得更加复杂。
    • @SeanM 你比大多数人更接近于他们通常第一次在 C 中尝试指针对指针的工作。无论如何,很高兴它有所帮助。祝你好运。
    • @SeanM 可能也应该提到这一点:您的 print 函数中存在内存泄漏。那条malloc 线路没有业务。这不是 Java 或 C#。
    • 是的,其他人对此发表了评论并删除了他们的评论,所以我修复了那部分。不过还是谢谢。
    猜你喜欢
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    相关资源
    最近更新 更多