逐行散列文本文件

时间:2019-05-22 10:53:13

标签: c database hash

我正在尝试对包含19行学生个人信息的文本文件进行哈希处理。有一个基于案例的系统,我可以选择要执行的操作,例如“插入哈希,显示等”。代码根本不会读取我提供的文本文件,当我按“显示”作为操作时,它将弹出没有。当我按插入选项等时,会发生同样的事情。

1 个答案:

答案 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);

AMfirst_name以及last_namegrade未初始化,行为未定义

您想要

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_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 $