【发布时间】:2021-07-05 07:12:01
【问题描述】:
我有这个 csv 文件包含联系人:
NAME, NUMBER, ADDRESS, EMAIL
Kevin Mahendra, +62 812-XXXX-XXXX, Jln.Anggrek Merah 3, kevinitsnovember@gmail.com
Adwi Lanang, +62 821-XXXX-XXXX, Jln.Ruhui Rahayu, adwilanang@gmail.com
Wasis Sirutama, +62 813-XXXX-XXXX, Jln.Pramuka 6 25, wasisnaruto@gmail.com
Alief Dean, +62 811-XXXX-XXXX, Jln.Padat Karya, aliefdean@gmail.com
Baharudin Nuri, +62 813-XXXX-XXXX, Jln.Ruhui Rahayu 1, baharudin008@yahoo.com
Yonggi Wijaya, +62 853-XXXX-XXXX, Jln.PM Noor Pondok S, yonggiwijaya@gmail.com
Artha Yoga, +62 822-XXXX-XXXX, Jln.A.Yani Gg.1, arthayoga97@gmail.com
Rusydi Nashier, +62 858-XXXX-XXXX, Jln.Perjuangan No.90, rusydinashier@gmail.com
Andre Pieters, +62 822-XXXX-XXXX, Jln.Villa Tamara No.1, azzahz@gmail.com
Paco Corleone, +62 816-XXXX-XXXX, Jln.Anggrek Merah 3, pacocorleone@gmail.com
这是我的 C 代码:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Number of buckets for TABLE
#define N 26
#define MAX 50
typedef struct Contact
{
char name[MAX];
char number[MAX];
char address[MAX];
char email[MAX];
struct Contact* next;
}
Contact;
void searching_contact(FILE *file);
void load_hash_table(FILE **file);
unsigned int hash(const char *name);
// Hash table
Contact *table[N];
int main(void)
{
// OPEN CSV FILE AS append and read mode
FILE *file = fopen("contacts.csv", "r");
if (file == NULL)
{
printf("Error open file!\n");
return 1;
}
searching_contact(file);
fclose(file);
return 0;
}
void searching_contact(FILE *file)
{
char name[MAX];
printf("Search Name: ");
scanf("%[^\n]%*c", name);
fflush(stdin);
// Load csv file into hash table first
load_hash_table(&file);
// Get index number by calling hash function
int hashIndex = hash(name);
printf("\n\nIndex number we get from searching: %i\n", hashIndex);
// Point to table that may contain the person
Contact *cursor = table[hashIndex];
// This will always print the last person
printf("The name on the table: %s\n", cursor->name);
// Keep traversing linked list in table
while (cursor != NULL)
{
// If the person found, print the contact information
if (strcmp(name, cursor->name) == 0)
{
printf("%s %s %s %s", cursor->name, cursor->number, cursor->address, cursor->email);
}
else
{
// If not the person, but in the same table, go to the next linked list
cursor = cursor->next;
}
}
printf("Not found!\n");
}
// FUNCTION TO LOAD CSV FILE INTO HASH TABLE
void load_hash_table(FILE **file)
{
Contact *new = malloc(sizeof(Contact));
if (new == NULL)
exit(1);
/*
"%[^,], "
Empty space or space after above sign will remove spaces or newline (\n) on each string
Just because, when we try to use hash function, the spaces or newline will also include
And we want to remove them so when user searching by name it will produce same hash index
*/
while(fscanf(*file, "%[^,], %[^,], %[^,], %[^\n] ", new->name, new->number, new->address, new->email) == 4)
{
// Skip header from CSV file
if (strcmp("NAME", new->name) == 0)
continue;
// Get index number from hash function with People name as input
int index = hash(new->name);
// Try to print name and it's index in csv file for debugging
printf("%s\n", new->name);
printf("%i\n", index);
/*
Create linked list point to WHAT inside Table[index]
For very first struct, it points to NULL, then store it in Table
Next struct, with the same Index number, it will point the first one
*/
new->next = table[index];
table[index] = new;
// Malloc for next fscanf
Contact *new = malloc(sizeof(Contact));
if (new == NULL)
exit(1);
}
}
// Hash function that will return index number from Table
unsigned int hash(const char *name)
{
// TODO
unsigned long hash = 5381;
int c;
while ((c = toupper(*name++)))
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash % N;
}
所以,我正在尝试制作一个程序,用户可以通过姓名搜索联系人。如您所见,我还想使用哈希表/哈希函数来锻炼。所以在搜索之前,它会将所有 csv 文件加载到哈希表中(参见load_hash_table())。但最终,即使用户已经输入了正确的姓名,它也总是找不到人。
我尝试仅使用 printf 进行调试。
首先,在load_hash_table() 函数中,我打印每个名称及其索引。它工作正常。它打印 csv 文件中的所有名称以及由hash 函数生成的正确索引。
其次,这是问题所在。当我尝试在 searching() 函数内打印时。它产生了正确且相同的 index 数字。但是当我打印名字时,它总是打印 csv 文件上的最后一个人,即 Paco Corleone。无论我们在 Table[] 中放入什么索引号,它总是会打印最后一个人的姓名。
我不明白。当 load_hash_table() 函数内的 while 循环 结束时,哈希表似乎丢失了之前已加载的所有数据。当你运行我给出的代码时,也许你会看到问题。请帮助我,我是 C 语言的新手,谢谢!
【问题讨论】: