The hash table stores phone numbers and names, uses the names as the keys. The problem I have is when I use the terminal window to enter the names and numbers.

The strange problem that occurs then is that all the names get the same phone number.
But when i hard code it works as it should, and that is exactly the same as when I use the terminal, except hard coded.

I've added hash,h and hash.c into the main.c file.
In the main section of the code I have marked what works and what does not work.

Does anyone know how I can solve this problem? I've tried different variations to make it through the terminal but nothing works.
Thanks in advanced.

#define HT_MAX_KEYLEN 50

struct ht_node {
  void *val;
  char *key;
  struct ht_node *nxt;
};

typedef struct ht {
  struct ht_node **tbl;
  int size;
} HT;

HT *ht_create(int size);                    /* allocate hashtable mem */
void ht_destroy(HT *ht);                    /* free hashtable mem */
void *ht_get(HT *ht, char *key);            /* retrieve entry */
void ht_put(HT *ht, char *key, void *val);  /* store entry */
void ht_remove(HT *ht, char *key);          /* remove entry */

/// above headerfile
/// down main
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
#include <string.h>

int main(){
    HT *ht;
    ht=ht_create(11);

   int n; 
     char namnet[20];
     char telefonen[20];

    do
    {
       printf("\n1-> name/telephone input");
        printf("\n2 -> get tel");
        scanf("%d",&n);
        switch(n)
        {
            case 1 :

                printf("\n\n\tEnter name: "); // <- this does not work, all names get same phone number
                scanf("%s",namnet);           // <- the number all names get is the last inputed
                printf("\n\n\tEnter tel : "); // <--------------||---------
                scanf("%s",telefonen);        // <---------------||---------
                ht_put(ht,namnet,telefonen);  // <---------------||---------
                //ht_put(ht,"peter","123");    <- this works, when i run case "2" i retrive correct numbers for the names
                //ht_put(ht,"johanna","987");  <- --------------||---------
                getch();
                break;

            case 2 :
                 printf("\n input name to get telnr ");
                 scanf("%s",namnet);
                 printf("%s",ht_get(ht,namnet));
                 getch();
                 break; 
         case 3 :
              ht_remove(ht,"johanna");

               break;
            case 5 :
                printf("\n\n\tThank You!");
                getch();
                break;
            default :
                printf("\n\n\tThe Specified Option Does Not Exist!");
                getch();
                break;
       }
    }while(n!=5);
    return 0;


    getch();
    ht_destroy(ht);

}
//above main
//down hash.c

//#include "hash.h"

unsigned long _hash(char *key)
{
  /* djb2 */
  unsigned long hash = 5381;
  int c;

  while (c = *key++)
    hash = ((hash << 5) + hash) + c;

  return hash;
}

HT *ht_create(int size)
{
  HT *ht = malloc(sizeof(HT));

  ht->size = size;

  ht->tbl = calloc(1, size * sizeof(struct ht_node *));

  return ht;
}

void ht_destroy(HT *ht)
{
  if (!ht) return;

  int i;
  for (i = 0; i < ht->size; i++) {
    struct ht_node *n = ht->tbl[i];
    while (n) {
      struct ht_node *n_old = n;

      n = n->nxt;

      free(n_old->key);
      n_old->key = NULL;
      free(n_old);
      n_old = NULL;
    }
  }

  free(ht->tbl);
  free(ht);

  ht = NULL;
}

void *ht_get(HT *ht, char *key)
{
  if (!ht) return NULL;

  unsigned long idx = _hash(key) % ht->size;

  struct ht_node *n = ht->tbl[idx];
  while (n) {
    if (strncmp(key, n->key, HT_MAX_KEYLEN) == 0)
      return n->val;

    n = n->nxt;
  }

  return NULL;
}

void ht_put(HT *ht, char *key, void *val)
{
  if (!ht) return;

  unsigned long idx = _hash(key) % ht->size;

  struct ht_node *n_new = calloc(1, sizeof(struct ht_node));
  n_new->val = val;
  n_new->key = calloc(1, strlen(key) + 1);
  strcpy(n_new->key, key);

  n_new->nxt = ht->tbl[idx];
  ht->tbl[idx] = n_new;
}

void ht_remove(HT *ht, char *key)
{
  if (!ht) return;

  unsigned long idx = _hash(key) % ht->size;

  struct ht_node *p = NULL, *n = ht->tbl[idx];
  while (n) {
    if (strncmp(key, n->key, HT_MAX_KEYLEN) == 0) {
      if (p)
        p->nxt = n->nxt;

      free (n->key);
      n->key = NULL;

      if (ht->tbl[idx] == n)
        ht->tbl[idx] = NULL;

      free (n);
      n = NULL;

      break;
    }

    p = n;
    n = n->nxt;
  }
}

Why is ht_put() receiving val as a void?

printf("\n\n\tEnter name: "); // <- this does not work, all names get same phone number

Add fflush(stdout); after the printf() to display it if it isn't working. Your input is being buffered...

Also, see this series about scanf() and what to use instead.

Edited 4 Years Ago by WaltP

This article has been dead for over six months. Start a new discussion instead.