我正在尝试对包含19行学生个人信息的文本文件进行哈希处理。有一个基于案例的系统,我可以选择要执行的操作,例如“插入哈希,显示等”。代码根本不会读取我提供的文本文件,当我按“显示”作为操作时,它将弹出没有。当我按插入选项等时,会发生同样的事情。
答案 0 :(得分:1)
代码根本不会读取我提供的文本文件
您的问题可能来自:
char line[4096]; while (fgets(line, sizeof line,fp)) { size_t len = strlen(line); if (len && (line[len - 1] != '\n'))
因为(line[len - 1] != '\n')
可能永远不会正确,因为 fgets 能够读取大行,并且在行仅包含少量数据之后考虑 fscanf 。
为什么要处理 / *不完整的行* / ?
完成测试的全部内容
if (len && (line[len - 1] == '\n'))
您还有一个意外的返回
if (!hashTable[hashIndex].head) { hashTable[hashIndex].head = newNode; hashTable[hashIndex].count = 1; return; }
因为这个原因,您不能阅读多个答案,所以请在else { ... }
请注意,您的代码还假设用户只要求次插入一次,如果他多次执行,则您将多次添加相同的元素。
读完一行后,您再次读入文件
fscanf(fp,"%s %s %s %d",node.AM, node.first_name, node.last_name, &node.grade);
所以您只需要保存一半的数据即可
sscanf(line,"%s %s %s %d",node.AM, node.first_name, node.last_name, &node.grade);
您还有其他问题
在哈希中,您假定标识符至少包含7个字符,如果不是这种情况,您会以不确定的行为从名称中读出(在空字符之后)
做类似的事情:
int Hash(char *AM, int n)
{
int i;
int hashIndex = 0;
for (i=0; (i< 8) && (AM[i] != 0); i++)
{
hashIndex += AM[i];
}
return hashIndex % n;
}
但是您的哈希值很差,但是有很多更好的方法来哈希字符串
在
fscanf(fp,"%s %s %s %d",node.AM, node.first_name, node.last_name, &node.grade);
您将格式%d 用于 int ,但是node.grade
是 float ,请替换%d < / em>按%f 并检查 fscanf 返回4
我还建议您限制读取字符串的大小,以免冒着写出字段的风险,因此(实际上, fscanf 必须替换为 sscanf )
fscanf(fp,"%99s %99s %99s %f", ...)
在
printf("Student ID : %d\n", myNode->AM);
和
printf("%-12d", myNode->AM);
您将格式%d 用于 int ,但您给出了char*
用 s 替换 d 或更改 AM 的类型(以及当然如何在其他地方读取和使用它)
insertToHash 结尾的返回是无用的,还有其他无用的 return 其他
在
printf("grade : %d\n", myNode->grade);
和
printf("%d\n", myNode->grade);
您将格式%d 用于 int ,但您要提供双精度
将%d 替换为%lf 或%lg 等
在
int hashIndex = Hash(AM, 19);
AM 未初始化,行为未定义
您想要
int hashIndex = Hash(node.AM, 19);
在
struct node *newnode = createNode(AM, first_name, last_name, grade);
AM
和first_name
以及last_name
和grade
未初始化,行为未定义
您想要
struct node *newnode = createNode(node.AM, node.first_name, node.last_name, node.grade);
并删除无用的变量hashIndex, grade, last_name, first_name, AM
在 deleteFromHash 和 searchInHash 测试中
if (myNode->AM == AM)
是错误的,因为您想要比较指针
if (!strcmp(myNode->AM, AM))
在
struct node { float grade; char AM[100]; char first_name[100]; char last_name[100]; struct node *next; }node;
对于结构体和全局变量使用相同的名称,这不是一个好主意。
此外,全局变量 node 仅在 insertToHash 中使用,因此您不需要它,删除全局变量并将局部变量添加到 insertToHash < / em>。
编辑后添加 main
scanf("%d", &AM);
必须是(2次)
scanf("%99s", AM);
您的变量first_name, last_name
和grade
未使用
考虑到我所有评论的代码是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
struct hash *hashTable = NULL;
int eleCount = 0;
struct Node
{
float grade;
char AM[100];
char first_name[100];
char last_name[100];
struct Node *next;
};
struct hash
{
struct Node *head;
int count;
};
struct Node * createNode(char *AM, char *first_name, char *last_name, float grade)
{
struct Node *newNode;
newNode = (struct Node *) malloc(sizeof(struct Node));
strcpy(newNode->AM, AM);
strcpy(newNode->last_name, last_name);
strcpy(newNode->first_name, first_name);
newNode->grade = grade;
newNode->next = NULL;
return newNode;
}
int Hash(char *AM, int n)
{
int i;
int hashIndex = 0;
for (i=0; (i< 8) && (AM[i] != 0); i++)
{
hashIndex += AM[i];
}
return hashIndex % n;
}
void insertToHash()
{
struct Node node;
FILE *fp;
fp = fopen ("Foitites-Vathmologio-DS.txt","rb");
if (fp == NULL)
{
fprintf(stderr,"Could not open file");
return;
}
char line[4096];
while (fgets(line, sizeof line,fp)) {
size_t len = strlen(line);
if (len && (line[len - 1] == '\n')) {
/* complete line */
if (sscanf(line,"%99s %99s %99s %f",node.AM, node.first_name, node.last_name, &node.grade) != 4) {
puts("invalid file");
return;
}
int hashIndex = Hash(node.AM, 19);
struct Node *newNode = createNode(node.AM, node.first_name, node.last_name, node.grade);
/* head of list for the bucket with index "hashIndex" */
if (!hashTable[hashIndex].head)
{
hashTable[hashIndex].head = newNode;
hashTable[hashIndex].count = 1;
}
else {
/* adding new Node to the list */
newNode->next = (hashTable[hashIndex].head);
/*
* update the head of the list and no of
* Nodes in the current bucket
*/
hashTable[hashIndex].head = newNode;
hashTable[hashIndex].count++;
}
}
}
fclose(fp);
printf("Done! \n");
}
void deleteFromHash(char *AM)
{
/* find the bucket using hash index */
int hashIndex = Hash(AM, 19);
int flag = 0;
struct Node *temp, *myNode;
/* get the list head from current bucket */
myNode = hashTable[hashIndex].head;
if (!myNode) {
printf("Given data is not present in hash Table!!\n");
return;
}
temp = myNode;
while (myNode != NULL) {
/* delete the Node with given AM */
if (!strcmp(myNode->AM, AM)) {
flag = 1;
if (myNode == hashTable[hashIndex].head)
hashTable[hashIndex].head = myNode->next;
else
temp->next = myNode->next;
hashTable[hashIndex].count--;
free(myNode);
break;
}
temp = myNode;
myNode = myNode->next;
}
if (flag)
printf("Data deleted successfully from Hash Table\n");
else
printf("Given data is not present in hash Table!!!!\n");
}
void searchInHash(char *AM) {
int hashIndex = Hash(AM, 19);
int flag = 0;
struct Node *myNode; myNode = hashTable[hashIndex].head;
if (!myNode) {
printf("Search element unavailable in hash table\n");
return;
}
while (myNode != NULL) {
if (!strcmp(myNode->AM, AM)) {
printf("Student ID : %s\n", myNode->AM);
printf("First Name : %s\n", myNode->first_name);
printf("Last Name : %s\n", myNode->last_name);
printf("grade : %lg\n", myNode->grade);
flag = 1;
break;
}
myNode = myNode->next;
}
if (!flag)
printf("Search element unavailable in hash table\n");
}
void display() {
struct Node *myNode;
int i;
for (i = 0; i < eleCount; i++) {
if (hashTable[i].count == 0)
continue;
myNode = hashTable[i].head;
if (!myNode)
continue;
printf("\nData at index %d in Hash Table:\n", i);
printf("Student ID First Name Last Name Grade \n");
printf("--------------------------------\n");
while (myNode != NULL) {
printf("%-12s", myNode->AM);
printf("%-15s", myNode->first_name);
printf("%-15s", myNode->last_name);
printf("%lg\n", myNode->grade);
myNode = myNode->next;
}
}
}
int main()
{
int n=19, ch;
char AM[100];
int insertDone = 0;
eleCount = n;
/* create hash table with "n" no of buckets */
hashTable = (struct hash *) calloc(n, sizeof(struct hash));
while (1) {
printf("\n1. Insertion\t2. Deletion\n");
printf("3. Searching\t4. Display\n5. Exit\n");
printf("Enter your choice:");
scanf("%d", &ch);
switch (ch) {
case 1:
if (insertDone)
puts("Inserton was already done");
else {
/*inserting new Node to hash table */
insertToHash();
insertDone = 1;
}
break;
case 2:
printf("Enter the AM to perform deletion:");
scanf("%99s", AM);
/* delete Node with "AM" from hash table */
deleteFromHash(AM);
break;
case 3:
printf("Enter the AM to search:");
scanf("%99s", AM);
searchInHash(AM);
break;
case 4:
display();
break;
case 5:
exit(0);
default:
printf("U have entered wrong option!!\n");
break;
}
}
return 0;
}
编译和执行:
pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra -Wall c.c
pi@raspberrypi:/tmp $ cat Foitites-Vathmologio-DS.txt
123 aze qsd 1.23
456 iop jkl 4.56
pi@raspberrypi:/tmp $ ./a.out
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:4
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:1
Done!
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:4
Data at index 7 in Hash Table:
Student ID First Name Last Name Grade
--------------------------------
456 iop jkl 4.56
Data at index 17 in Hash Table:
Student ID First Name Last Name Grade
--------------------------------
123 aze qsd 1.23
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:1
Inserton was already done
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:3
Enter the AM to search:123
Student ID : 123
First Name : aze
Last Name : qsd
grade : 1.23
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:3
Enter the AM to search:1234
Search element unavailable in hash table
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:2
Enter the AM to perform deletion:1
Given data is not present in hash Table!!
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:2
Enter the AM to perform deletion:123
Data deleted successfully from Hash Table
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:4
Data at index 7 in Hash Table:
Student ID First Name Last Name Grade
--------------------------------
456 iop jkl 4.56
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:2
Enter the AM to perform deletion:456
Data deleted successfully from Hash Table
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:4
1. Insertion 2. Deletion
3. Searching 4. Display
5. Exit
Enter your choice:5
pi@raspberrypi:/tmp $