C中哈希表程序中的指针问题
Posted
技术标签:
【中文标题】C中哈希表程序中的指针问题【英文标题】:Problem With Pointers in Hash Table program in C 【发布时间】:2021-12-01 12:37:12 【问题描述】:所以我正在制作一个列表数组,其中列表存储在由哈希函数定义的索引中,并且列表存储一个结构项目,该项目存储来自 csv 文件的数据,但我真的不知道如何将结构项目存储在名单。我尝试为它制作一个程序,但它没有输出任何东西。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BUFFER 20 // Maximum string length this program can handle
#define MAX_NB_POKEMON 22 // Maximum number of Pokemons
#define ARRAY_SIZE 59
typedef struct Pokemon Pokemon;
struct Pokemon
int id, age;
char surname[MAX_BUFFER], depid[MAX_BUFFER],forename[MAX_BUFFER], type[MAX_BUFFER], gender[MAX_BUFFER],nationality[MAX_BUFFER],rel[MAX_BUFFER],occ[MAX_BUFFER];
;
// The CSV parser
int next_field( FILE *f, char *buf, int max )
int i=0, end=0, quoted=0;
for(;;)
// fetch the next character from file
buf[i] = fgetc(f);
// if we encounter quotes then flip our state and immediately fetch next char
if(buf[i]=='"') quoted=!quoted; buf[i] = fgetc(f);
// end of field on comma if we're not inside quotes
if(buf[i]==',' && !quoted) break;
// end record on newline or end of file
if(feof(f) || buf[i]=='\n') end=1; break;
// truncate fields that would overflow the buffer
if( i<max-1 ) ++i;
buf[i] = 0; // null terminate the string
return end; // flag stating whether or not this is end of the line
// Stuff to make life a bit neater in main
void fetch_pokemon ( FILE *csv, struct Pokemon *p)
char buf[MAX_BUFFER];
next_field( csv, buf, MAX_BUFFER ); // load id into buffer as string
p->id = atoi(buf); // then parse to integer
next_field( csv, p->depid, MAX_BUFFER ); // name and type are just strings so read
next_field( csv, p->surname, MAX_BUFFER ); // those directly into the struct
next_field( csv, p->forename, MAX_BUFFER );
// Load all the pokemon's stats from the file using buffer as intermediary
next_field( csv, buf, MAX_BUFFER );
p->age = atoi(buf); // atoi stands for ASCII to Integer
next_field( csv, p->type, MAX_BUFFER );
next_field( csv, p->gender, MAX_BUFFER );
next_field( csv, p->nationality, MAX_BUFFER );
next_field( csv, p->rel, MAX_BUFFER );
next_field( csv, p->occ, MAX_BUFFER );
int hash_function(char* s)
int hash = 0;
while(*s)
hash = (hash + *s)%ARRAY_SIZE;
s++;
return hash;
void print_pokemon( struct Pokemon *p )
printf("%d\t%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t\n", p->id,p->depid,p->surname,p->forename,p->age,p->type,p->gender,p->nationality,p->rel,p->occ);
typedef struct LinkedList LinkedList;
// Define the Linkedlist here
struct LinkedList
Pokemon* item;
LinkedList* next;
;
LinkedList* allocate_list ()
// Allocates memory for a Linkedlist pointer
LinkedList* list = (LinkedList*) malloc (sizeof(LinkedList));
return list;
LinkedList* linkedlist_insert(LinkedList* list, Pokemon* item)
// Inserts the item onto the Linked List
if (!list)
LinkedList* head = allocate_list();
head->item = item;
head->next = NULL;
list = head;
return list;
else if (list->next == NULL)
LinkedList* node = allocate_list();
node->item = item;
node->next = NULL;
list->next = node;
return list;
LinkedList* temp = list;
while (temp->next->next)
temp = temp->next;
LinkedList* node = allocate_list();
node->item = item;
node->next = NULL;
temp->next = node;
return list;
void free_linkedlist(LinkedList* list)
LinkedList* temp = list;
while (list)
temp = list;
free(temp->item);
free(temp);
LinkedList* hashTable[ARRAY_SIZE]=0;
void print_table(void)
printf("Start\n");
int i;
for(i=0;i<ARRAY_SIZE;i++)
if(hashTable[i] == NULL)
printf("\t%i\t---\n",i);
else
printf("%d\t%s\t%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t\n", hashTable[i]->item->id,hashTable[i]->item->depid,hashTable[i]->item->surname,hashTable[i]->item->forename,hashTable[i]->item->age,hashTable[i]->item->type,hashTable[i]->item->gender,hashTable[i]->item->nationality,hashTable[i]->item->rel,hashTable[i]->item->occ);
printf("End\n");
int main ()
FILE *f;
Pokemon pArray[MAX_NB_POKEMON];
Pokemon p;
// char* a;
int a;
// Try to open the input file. If there is a problem, report failure and quit
f = fopen(".csv", "r"); //the csv file is loaded here
if(!f)
printf("unable to open file\n");
return EXIT_FAILURE;
fetch_pokemon( f, &p ); // discard the header data in the first line
// Now read and print pokemon until the end of the file
int nbPokemons = 0;
//printf("Person ID Deposition ID Surname Forename Age Person Type Gender\tNationality\tReligion Occupation\n");
while(!feof(f))
fetch_pokemon( f, &pArray[nbPokemons] );
a=hash_function(pArray[nbPokemons].surname);
LinkedList* d=allocate_list();
d->item=&pArray[nbPokemons];
hashTable[a]=d;
free_linkedlist(d);
printf("%d\n",a);
// check(&pArray[nbPokemons]);
// strcpy(a,pArray[nbPokemons].surname);
print_pokemon( &pArray[nbPokemons] );
// printf("\n");
nbPokemons++;
// print_table();
// print_pokemon(&pArray[5]);
fclose(f);
return EXIT_SUCCESS;
'''
【问题讨论】:
if(feof(f) ||
为时已晚。使用int ch = fgetc(f); if (ch == EOF) break; buf[i] = ch; ...
。也许还有其他问题。
#define MAX_BUFFER 20 // Maximum string length this program can handle
, char surname[MAX_BUFFER]
是有问题的。对于 20 的最大 length 字符串,需要 21 的缓冲区 size。但没有发布的意见,不清楚这是否会影响 OP 的案例。
请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。
【参考方案1】:
您忘记在main
中的LinkedList* d=allocate_list();
之后将d->next
设置为NULL
;最好加一行
if (list) list->next = NULL;
在allocate_list
中,因此您可以将linkedlist_insert
中的所有…->next = NULL;
删除。
free_linkedlist
中有两个错误。
-
你不能
free(temp->item);
,因为item
不是malloc
d,而是设置为&pArray[nbPokemons]
。
您忘记将list
推进到next
节点。
更正后的 free_linkedlist
可能是 e。 g.
void free_linkedlist(LinkedList *list)
for (LinkedList *temp; list; list = temp) temp = list->next, free(list);
【讨论】:
以上是关于C中哈希表程序中的指针问题的主要内容,如果未能解决你的问题,请参考以下文章