我正在尝试对包含 19 行学生个人信息的文本文件进行哈希处理。有一个基于案例的系统,我可以选择我想要执行的操作,例如插入哈希、显示等。代码根本不会读取我提供的文本文件,当我按“显示”作为操作时,它会显示没有什么。当我按下“插入”选择等时,也会发生同样的事情。
最佳答案
The code simply won't read the text file I have provided
您的问题可能来自:
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);
您对 int 使用格式 %d,但 node.grade
是 float,替换 < em>%d 由 %f 并检查 fscanf 返回 4
我还鼓励您限制读取字符串的大小,以免冒险写出字段,因此(事实上,fscanf必须替换为sscanf )
fscanf(fp,"%99s %99s %99s %f", ...)
在
printf("Student ID : %d\n", myNode->AM);
和
printf("%-12d", myNode->AM);
您对 int 使用格式 %d,但给出 char*
将d替换为s或更改AM的类型(当然还有如何在其他地方读取和使用它)
insertToHash最后的return是没用的,还有一些其他没用的return else在哪里
在
printf("grade : %d\n", myNode->grade);
和
printf("%d\n", myNode->grade);
您对 int 使用格式 %d,但给出了 double
将 %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 $
关于c - 逐行散列文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56255196/