由于scanf(),哈希表无法工作

时间:2017-09-16 06:33:01

标签: c linked-list segmentation-fault scanf hashtable

我正在学习C数据结构。我有以下代码,导致分段错误。 我已经使用了K& R C(第二版)中的哈希函数。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 101

typedef struct Details
{
    char *name;
    float checkTotal;
    float tipTotal;
    int numReciepts;
    struct Details *next;
    struct Details *prev;
} det;

static det *hashtab[HASHSIZE];

char *str_dup(char *);
det *lookup(char *);
det *insert(char *, float, float);
unsigned hash(char *);
void printData(char *);
int main()
{
    printf("1. Enter details.\n");
    printf("2. Print List of employees.\n");
    char *s;
    float cT; //checkTotal
    float tT; //tipTotal
    while (1)
    {
        int command = 0;
        printf("Enter option: ");
        scanf("%d", &command);
        if (command == 1)
        {
            printf("Enter name: ");
            scanf("%s", s);
            printf("Enter check total: ");
            scanf("%f", &cT);
            printf("Enter tip total: ");
            scanf("%f", &tT);
            insert(s, cT, tT);
        }
        else if (command == 2)
        {
            char *p;
            printf("Enter name of employee: ");
            scanf("%s", p); //including this line causes seg fault.
            printData(p);
        }
        else
            break;
    }
    return 0;
}

unsigned hash(char *s)
{
    unsigned hashval;
    for (hashval = 0; *s != '\0'; *s++)
        hashval = *s + 31 * hashval;
    return hashval % HASHSIZE;
}
det *lookup(char *name)
{
    det *ptr;
    for (ptr = hashtab[hash(name)]; ptr != NULL; ptr = ptr->next)
    {
        if (strcmp(name, ptr->name) == 0)
            return ptr;
    }
    return NULL;
}

det *insert(char *name, float cT, float tT)
{
    det *new;
    unsigned hashval;
    if ((new = lookup(name)) == NULL)
    {
        new = (det *)malloc(sizeof(new));
        if (new == NULL || (new->name = str_dup(name)) == NULL)
            return NULL;
        hashval = hash(name);
        new->next = hashtab[hashval];
        hashtab[hashval] = new;
        new->checkTotal += cT;
        new->tipTotal += tT;
        new->numReciepts++;
        printf("Details of '%s' inserted.\n", name);
    }
    else
    {
        new->checkTotal += cT;
        new->tipTotal += tT;
        new->numReciepts++;
        printf("Details of '%s' updated.\n", name);
    }
}
char *str_dup(char *s)
{
    char *p;
    p = (char *)malloc(strlen(s) + 1);
    if (p != NULL)
        strcpy(p, s);
    return p;
}

void printData(char *p)
{
    det *ptr;
    if ((ptr = lookup(p)) != NULL)
    {
        printf("Emplyee Name  : %s\n", ptr->name);
        printf("Total amount  : %6.2f\n", ptr->checkTotal);
        printf("Total tip     : %6.2f\n", ptr->tipTotal);
        printf("Total reciepts: %6.2d\n", ptr->numReciepts);
    }
    else
    {
        printf("Employee '%s' does not exist.\n", p);
        return;
    }
}

如果 else if:main 中没有 scanf(),那么每件事情都可以。使用硬编码字符串调用 printData()也可以。

其他如果:主中包含 scanf()会在提示输入名称后导致分段错误

我已经尝试过,想不到原因。据我所知:

  1. 中的代码if:main 未访问中的任何内容if:else

  2. if 不会因为其他错误而导致错误,如果,即使错误也是如此。 (至少在这种情况下,或据我的理解而言)

  3. 非常感谢所有专家的未来提示!

    P.S: scanf():如果工作正常。

0 个答案:

没有答案