将 .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);
我最近一直在尝试学习哈希-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);