Хеширование текстового файла построчно

Я пытаюсь хешировать текстовый файл, содержащий 19 строк личной информации ученика. Существует система, основанная на прецедентах, в которой я могу выбрать, какое действие я хочу выполнить, например, «Вставить в хеш», «Отобразить» и т. д. Код просто не будет читать текстовый файл, который я предоставил, и когда я нажму «Отобразить» в качестве действия, он вызовет ничего. То же самое произойдет, когда я нажму кнопку «Вставить» и т. д.

Вы звоните Hash на неинициализированный указатель int hashIndex = Hash(AM, 19); вы хотели вызвать int hashIndex = Hash(node.AM, 19);?

kiran Biradar 22.05.2019 13:24

@kiran Biradar Я написал свой код на основе этого сообщения, поэтому я думаю, что это отвечает на ваш вопрос stackoverflow.com/questions/56226055/…

vaskar 22.05.2019 13:37

Прочтите Как спросить

klutt 22.05.2019 14:04

Рекомендуется предоставить краткий, но полный компилируемый пример, показывающий конкретные проблемы, с которыми вы столкнулись. В этом случае вы предоставили слишком много плохо отформатированного кода (который с тех пор был отредактирован), но он не содержит функции int main(void) или int main(int argc, char *argv[]), поэтому он не будет скомпилирован. Пожалуйста, отредактируйте свой пост, чтобы указать, как вы написали свою основную функцию.

ryyker 22.05.2019 14:17

Для меня (line[len - 1] != '\n') должно быть (line[len - 1] == '\n'), а у вас несколько других проблем, смотрите мой ответ

bruno 22.05.2019 14:26

@ryyker я редактировал в своей основной функции

vaskar 22.05.2019 14:58

@vaskar у тебя тоже проблемы с основной, я отредактировал свой ответ

bruno 22.05.2019 15:05
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
7
635
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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 может читать большую строку и учитывая, что фсканф после строк содержит только несколько данных.

Почему вы хотите работать над /* неполная строка */?

Работа над полными строками с тестом

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 для инт, но node.grade является плавать, замените %d на %f, а также проверьте, что фсканф возвращает 4

Я также рекомендую вам ограничить размер считываемой строки, чтобы не рисковать записью за пределы полей, поэтому (на самом деле фсканф необходимо заменить на sscanf)

fscanf(fp,"%99s %99s %99s %f", ...)

В

printf("Student ID  : %d\n", myNode->AM);

а также

printf("%-12d", myNode->AM);

вы используете формат %d для инт, но вы даете char*

Замените д на с или измените тип ЯВЛЯЮСЬ (и, конечно, как его читать и использовать в другом месте)

Возврат в конце вставитьтохэш бесполезен, там еще какие-то бесполезные вернуть еще где

В

printf("grade      : %d\n", myNode->grade);

а также

printf("%d\n", myNode->grade);

вы используете формат %d для инт, но вы даете двойной

Замените %d на %lf или %lg и т. д.

В

int hashIndex = Hash(AM, 19);

ЯВЛЯЮСЬ не инициализирован, поведение не определено

Вы хотели

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

В удалить из хэша и 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;

одно и то же имя используется для структуры и глобальной переменной, это не очень хорошая идея.

Также глобальная переменная узел используется только в вставитьтохэш, поэтому она вам не нужна, удалите глобальную переменную и добавьте локальную переменную в вставитьтохэш.


После редактирования добавьте основной

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 $ 

Я думаю, что мы делаем некоторые успехи здесь! Прежде чем я внесу изменения в основную функцию и, в частности, в scaf("%d", &AM) , когда я выберу вариант отображения, он отобразит только первую строку моего файла, но после предложенного вами изменения я получаю return ld1 exit положение дел

vaskar 22.05.2019 15:19

@vaskar Я продолжаю исправлять ваш код, и в настоящее время на дисплее отображаются записи, которые я поместил в файл.

bruno 22.05.2019 15:23

Я отредактировал код mu с внесенными вами исправлениями вместе с содержимым и формой моего файла .txt, и теперь, когда я выбираю «Показать», он показывает двух или трех студентов одновременно, как если бы они были в одном узле.

vaskar 22.05.2019 15:48

@vaskar Я продолжаю редактировать свой ответ, чтобы исправить ваш код, пожалуйста, подождите, я закончу, я предупрежу вас, а также поставлю полный исправленный код

bruno 22.05.2019 15:50

@vaskar готово, я выложил полный исправленный код и пример выполнения, но прочитал весь мой ответ, чтобы понять изменения

bruno 22.05.2019 16:03

Я реализовал ваш код в своем текстовом файле, и хотя он работает так, как вы описываете, когда я выбираю параметр «Отображение», я получаю некоторые узлы, содержащие одну запись, а некоторые — 2-3. Я поместил результаты в свой исходный пост, который я отредактировал! Наконец, я уже проголосовал за ваш ответ, который действительно был очень полезен, но из-за моей репутации он не будет учитываться :( Я отметил ваш вопрос как принятый!

vaskar 22.05.2019 16:56

Плюс один только за ваши обширные усилия.

ryyker 22.05.2019 17:09

@bruno У меня есть, да. Спасибо за вашу помощь!

vaskar 22.05.2019 17:16

Другие вопросы по теме