c - 逐行散列文本文件

标签 c database hash

我正在尝试对包含 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.gradefloat,替换 < 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);

AMfirst_namelast_namegrade 未初始化,行为未定义

你想要

struct node *newnode = createNode(node.AM, node.first_name, node.last_name, node.grade);

并删除无用的变量hashIndex,grade,last_name,first_name,AM

deleteFromHashsearchInHash中进行测试

 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_namegrade未使用

<小时/>

考虑到我所有言论的代码是:

#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/

相关文章:

将相似的字符串散列到相同的散列值

c# - 为 C# 保留局部性的哈希函数

mysql - mysql memcached ndb 集群中如何进行更新

sql - 将 PL/SQL 代码运行到 Oracle 11g Express Edition - 错误

sql - 为什么 ColdFusion 哈希函数在这些场景中会返回不同的结果?

c - 为什么表达式和语句之间存在差异

c++ - 直接用变量设置指针意味着什么?

c - 为什么使用 %ebx 寄存器会导致我的汇编代码出现段错误

c - C中null语句的使用

javascript - 如何通过单击按钮(传递了按钮 'data')来运行 PHP 函数?