C:链接列表哈希表填充问题

时间:2016-07-27 19:21:41

标签: c list dictionary hashtable

我是C的新手,目前正在编写拼写检查程序。为此,我首先将单词字典加载到哈希表中以便于引用。这是我的代码:

bool load(const char* dictionary)
{
    typedef struct node
    {
        char word[LENGTH + 1];
        struct node* next;
    }
    node;

    node* table[500];

    FILE *fp;
    fp = fopen("dictionaries/small", "r");

    if(fp == NULL)
    {
        return 0;
    }

    node* new_node = malloc(sizeof(node));
    fscanf(fp, "%s", new_node->word);
    int hashed_word = hash_function(new_node->word);

    if(table[hashed_word] == NULL) //if the table has no value at the index
    {
        table[hashed_word]->word = new_node->word; //Issue here
    }  
    return 0;
}

此代码非常简单地读取文件的第一行(单词)然后对其进行哈希处理(第一个单词' cat'给出2的哈希值)。然后我检查表是否在散列函数给出的索引处有一个单词。

然后,我想要创建一个链接列表,第一个链接是第一个单词(' cat'),然后我从那里构建它。但是,当我运行此代码时,我遇到了一个问题:

table[hashed_word]->word = new_node->word; //Issue here

并收到此错误:

dictionary.c:66:34: error: array type 'char [46]' is not assignable
    table[hashed_word]->word = new_node->word;
    ~~~~~~~~~~~~~~~~~~~~~~~~ ^
1 error generated.

我认为这一行会分配'字'表的一部分是“猫”。 (new_node的一部分),但它没有

请有人能告诉我我做错了什么吗?我认为它非常重要,因为指针令人困惑!我已经被困在这几天了,我开始有点沮丧,所以会喜欢任何可以提供的帮助。

1 个答案:

答案 0 :(得分:2)

您正在创建一个包含500个指针的表,但您并未将其初始化为任何内容。然后你去检查元素是否为null,它们可能是也可能不是(它们只是垃圾)。

当您尝试添加单词时,您尝试将其写入表中已有的节点,而不是仅将新分配的节点链接到表中。

您的表也是一个局部变量,因此在load函数返回后将无法访问。

上述所有内容的最简单修复方法是使您的表和struct node定义全局:

typedef struct node
{
    char word[LENGTH + 1];
    struct node* next;
} node;

node *table[500] = { 0 };

然后使用循环填写表格;

bool load(const char* dictionary)
{
    char word[256];
    FILE *fp = fopen("dictionaries/small", "r");
    if(fp == NULL)
        return false;

    while (fscanf(fp, "%255s", word) == 1) {
        if (strlen(word) > LENGTH)
            continue;  // ignore words that are too long
        int hashed_word = hash_function(word);
        node* new_node = malloc(sizeof(node));
        strcpy(new_node->word, word);
        new_node->next = table[hashed_word];
        table[hashed_word] = new_node;
    }
    fclose(fp);
    return true;
}