将 .dat 文件中的 strings/lines 添加到 C 中的散列 table

Adding strings/lines from .dat file to a hash table in C

我最近一直在尝试学习哈希-tables,这样我就可以从 .dat 文件中加载行。这是为了减少我花在查看文档中某些行的次数。在浏览了一些论坛、教程网站和 youtube 视频后,我起草了如下所示的代码。

到目前为止,我的问题是使用 void fileread(char *FILE_NAME) 将 .dat 中的行保存到哈希-table,当我打印 table 时,我得到了乱码。据我所知,我得到的代码基本上只是保存指针,所以最后所有指针都指向同一个数组char svaret[MAX_LIST]={};,我试图将其同时用于二维数组和全局变量,非其中的工作。我想我知道出了什么问题,但我真的不知道如何解决这个问题。我必须编写另一种类型的哈希码吗?

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

#define MAX_LIST 109
#define TABLE_SIZE 35

char FILE_MOVE_SET[]="Rubix Move Set.dat";

typedef struct move_info{
    char move_set[MAX_LIST];
    int move_length;
    struct move_info *next;
}move_info;

move_info *hash_table[TABLE_SIZE];
move_info *lookup_hash_table(char *move_set);
bool insert_hash_table(move_info *p);
int hash(char *move_set);
bool init_hash_table();
void print_table();
void fileread(char *FILE_NAME);



int main(){

    init_hash_table();

    print_table();

    fileread(FILE_MOVE_SET);

    print_table();

}

int hash(char *move_set){

    int legnth=strlen(move_set);
    unsigned int hash_value=0;

    for(int x=0;x<legnth;x++){
        hash_value+=move_set[x]*(move_set[x]+TABLE_SIZE)*x;
        hash_value=(hash_value*move_set[x])%TABLE_SIZE;
    }
    return hash_value;
}

bool init_hash_table(){
    for(int x=0;x<TABLE_SIZE;x++)
        hash_table[x]=NULL;
}

void print_table(){

    printf("TABLE START\n");

    for(int x=0;x<TABLE_SIZE;x++){

        if(hash_table[x]==NULL)
            printf("\t%i\t-----\n",x);

        else{
            printf("\t%i\t",x);
            move_info *tmp = hash_table[x];

            while(tmp!=NULL){
                printf("%s[%i] -",tmp->move_set,tmp->move_length);
                tmp=tmp->next;
            }
            printf("\n");
        }
    }
    printf("TABLE END\n");

}

bool insert_hash_table(move_info *p){

    if(p==NULL)
        return false;

    int index=hash(p->move_set);

    p->next=hash_table[index];
    hash_table[index]=p;

    return true;

}

move_info *lookup_hash_table(char *move_set){

    int index=hash(move_set);
    move_info *tmp=hash_table[index];

    while(tmp !=NULL && strcmp(tmp->move_set,move_set)!=0)
        tmp=tmp->next;

    return tmp;

}

void fileread(char *FILE_NAME){

    char svaret[MAX_LIST]={};
    move_info from_file;
    FILE *fr = fopen(FILE_NAME, "r+");

    if(fr!=NULL){
        while (fgets(svaret, MAX_LIST, fr) != NULL ){

            if(svaret[0]=='\n')
                break;

            int y=strlen(svaret)-1;
            svaret[y]='[=12=]';

            for(int x=0;x<y+1;x++)
                from_file.move_set[x]=svaret[x];

            from_file.move_length=y;

            insert_hash_table(&from_file);
        }
    }

    fclose(fr);

}

你或多或少给出了问题的答案:

As far as I can tell the code I got basically just saves pointers, so in the end all pointers point to the same array

您保存的指针是函数 fileread 指向 from_file 的指针(即定义为 move_info from_file;)。

这是错误的。永远不要保存(或 return)指向函数局部变量的指针。一旦函数returns,这些变量就结束了它们的生命。所以你有一个指向 "dead" 变量的指针。

在您的情况下,您需要动态分配。动态分配的变量将 "stay alive" 直到您决定不再需要它(然后您调用 free)。

要使用动态分配,您需要类似的东西:

move_info from_file; ---> move_info *p_from_file = malloc(sizeof *p_from_file);

p_from_file 现在是 指向 move_info 类型对象的指针 。您可以将该指针保存在您的散列 table 中并稍后使用该对象 - 也在函数 returns.

之后

注意:您需要修改该函数的其他部分才能使用指针 - 示例:

        from_file.move_length=y;  ---> p_from_file->move_length=y;

        insert_hash_table(&from_file); ---> insert_hash_table(p_from_file);