簡體   English   中英

使用符號表的C程序輸出錯誤

[英]Wrong output for C program using symbol tables

我現在有這段代碼,並且得到了我無法理解的輸出。

這是我的symTable模塊,它具有操作符號表所需的所有功能。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include "symTable.h"
#define HASH_MULTIPLIER 65599
#define SIZE 61

struct SymTable {
    char *key;
    void *value;
    struct SymTable *next;
};

/*--------------------------------------------------------------------*/

/* Hash string str to a hash table bucket index in range [0, htsize] */

static unsigned int hash(const char *key, const int htsize)
{
    int i;
    unsigned int h = 0U;
    for (i = 0; key[i] != '\0'; i++)
        h = h * HASH_MULTIPLIER + (unsigned char) key[i];
    return h % htsize;
}

SymTable_T symTable_create(void)
{


    SymTable_T p;
    p = calloc(SIZE, sizeof(SymTable_T));
    p->key = (char*)calloc(1, sizeof(char));;

    return p;
}


void symTable_destroy(SymTable_T symTable)
{


    SymTable_T p, nextp;
    int i;

    assert(symTable != NULL);

    for (i = 0; i < SIZE; i++) {
        for (p = symTable; p != NULL; p = nextp) {
            nextp = p->next;
            assert(p->key != NULL);
            p=NULL;
        }
    }
    free(symTable);
    return;

}

int symTable_size(SymTable_T symTable)
{

    SymTable_T p, nextp;
    int i=0;
    assert(symTable != NULL);
    for (p = symTable; p != NULL; p = nextp) {
        nextp = p->next;
        i++;
    }

    return i;

}

int symTable_insert(SymTable_T symTable, const char *key,
                    const void *value, size_t valuesize)
{

    SymTable_T p, prevp = NULL;
    int h;


    assert(symTable != NULL);

    if (key == NULL)
        return 0;                   // insert failed: return 0

    /* Get hash of key*/
    h = hash(key, SIZE);


    for (p = symTable; p != NULL; prevp = p, p = p->next) {

        if (hash(p->key, SIZE) == h)
        {
            return 0;
        }

    }

    p = (SymTable_T)malloc(sizeof(SymTable_T));
    if (p == NULL)
        return 0;
    p->key =(char*) key;
    p->value = (void*)calloc(1, valuesize);
    memcpy(p->value, value, valuesize);
    p->next = NULL;
    if (symTable == NULL)
        symTable = p;
    else
        prevp->next = p;
    return 1;
}

int symTable_search(SymTable_T symTable, const char *key,
                    void *value, size_t valuesize)
{

    SymTable_T p;
    int i;
    assert(symTable != NULL);
    for (i = 0; i < SIZE; i++) {

        for (p = symTable->next; p != NULL; p = p->next) {
            if (strcmp(p->key, key) == 0)
            {
                //value = (void*)calloc(1, valuesize);
                memcpy(value, p->value, valuesize);
                //  printf("%c"()
                return 1;
            }

        }
    }
    return 0;

}

int symTable_delete(SymTable_T symTable, const char *key)
{
    SymTable_T p, nextp;
    int i;
    assert(symTable != NULL);
    for (i = 0; i < SIZE; i++) {
        for (p = symTable->next; p != NULL; p = nextp) {
            nextp = p->next;

            assert(p->key != NULL);
            if (strcmp(p->key, key) == 0)
            {

                p = NULL;
                return 1;
            }
        }
    }
    return 0;
}

我有一個標頭和一個C客戶端文件來運行該程序。

主要客戶端文件是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symTable.h"

int main(int argc, char *argv[])
{
    char *key[4] = { "Einstein", "Newton", "Bohr", "Curie" };
    char cvalue, char_value[4] = { 'e', 'n', 'b', 'c' };
    int  ivalue, int_value[4] = { 10, 20, 30, 40 };
    float fvalue, float_value[4] = { 1.11, 2.22, 3.33, 4.44 };
    double darray[2], double_array[4][2] = { { 1.11, 2.22 },
                    { 3.33, 4.44 }, { 5.55, 6.66 }, { 7.77, 8.88 } };

    int i, rv;

    SymTable_T charTable, intTable, floatTable, double_arrayTable;

    /* Create and insert character values into symbol table. */
    printf("\nCreating symbol table with character values\n");
    printf("-------------------------------------------\n");
    charTable = symTable_create();
    if (charTable == NULL) {
        fprintf(stderr, "Cannot create character table\n");
        return 1;
    }
    for (i = 0; i < 4; i++) {
        printf("Insert <%s, %c>\n", key[i], char_value[i]);
        rv = symTable_insert(charTable, key[i], &char_value[i], sizeof(char));
        if (!rv) {
            fprintf(stderr, "Insert failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Create and insert integer values into symbol table. */
    printf("\nCreating symbol table with integer values\n");
    printf("-----------------------------------------\n");
    intTable = symTable_create();
    if (intTable == NULL) {
        fprintf(stderr, "Cannot create integer table\n");
        return 1;
    }
    for (i = 0; i < 4; i++) {
        printf("Insert <%s, %d>\n", key[i], int_value[i]);
        rv = symTable_insert(intTable, key[i], &int_value[i], sizeof(int));
        if (!rv) {
            fprintf(stderr, "Insert failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Create and insert float values into symbol table. */
    printf("\nCreating symbol table with float values\n");
    printf("---------------------------------------\n");
    floatTable = symTable_create();
    if (floatTable == NULL) {
        fprintf(stderr, "Cannot create float table\n");
        return 1;
    }
    for (i = 0; i < 4; i++) {
        printf("Insert <%s, %g>\n", key[i], float_value[i]);
        rv = symTable_insert(floatTable, key[i], &float_value[i], sizeof(float));
        if (!rv) {
            fprintf(stderr, "Insert failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Create and insert an array two double values into symbol table. */
    printf("\nCreating symbol table with arrays of two double values\n");
    printf("------------------------------------------------------\n");
    double_arrayTable = symTable_create();
    if (double_arrayTable == NULL) {
        fprintf(stderr, "Cannot create double array table\n");
        return 1;
    }
    for (i = 0; i < 4; i++) {
        printf("Insert <%s, [%g, %g]>\n", key[i], double_array[i][0], double_array[i][1]);
        rv = symTable_insert(double_arrayTable, key[i], &double_array[i][0], 2*sizeof(double));
        if (!rv) {
            fprintf(stderr, "Insert failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Search and print <key, value> pairs in character table, then delete */
    printf("\nSearching symbol table with character values\n");
    printf("--------------------------------------------\n");
    for (i = 0; i < 4; i++) {
        rv = symTable_search(charTable, key[i], &cvalue, sizeof(char));
        if (rv) {
            printf("%s found, value = %c: now deleting\n", key[i], cvalue);
            if (!symTable_delete(charTable, key[i])) {
                fprintf(stderr, "Delete failed for %s\n", key[i]);
                return 1;
            }
        }
        else  {
            fprintf(stderr, "Search failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Search and print <key, value> pairs in integer table, then delete */
    printf("\nSearching symbol table with integer values\n");
    printf("------------------------------------------\n");
    for (i = 0; i < 4; i++) {
        rv = symTable_search(intTable, key[i], &ivalue, sizeof(int));
        if (rv) {
            printf("%s found, value = %d: now deleting\n", key[i], ivalue);
            if (!symTable_delete(intTable, key[i])) {
                fprintf(stderr, "Delete failed for %s\n", key[i]);
                return 1;
            }
        }
        else  {
            fprintf(stderr, "Search failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Search and print <key, value> pairs in float table, then delete */
    printf("\nSearching symbol table with float values\n");
    printf("----------------------------------------\n");
    for (i = 0; i < 4; i++) {
        rv = symTable_search(floatTable, key[i], &fvalue, sizeof(float));
        if (rv) {
            printf("%s found, value = %g: now deleting\n", key[i], fvalue);
            if (!symTable_delete(floatTable, key[i])) {
                fprintf(stderr, "Delete failed for %s\n", key[i]);
                return 1;
            }
        }
        else  {
            fprintf(stderr, "Search failed for %s\n", key[i]);
            return 1;
        }
    }

    /* Search and print <key, value> pairs in double array table, then delete */
    printf("\nSearching symbol table with arrays of two double values\n");
    printf("-------------------------------------------------------\n");
    for (i = 0; i < 4; i++) {
        rv = symTable_search(double_arrayTable, key[i], &darray, 2*sizeof(double));
        if (rv) {
            printf("%s found, value = [%g, %g]: now deleting\n", key[i], darray[0], darray[1]);
            if (!symTable_delete(double_arrayTable, key[i])) {
                fprintf(stderr, "Delete failed for %s\n", key[i]);
                return 1;
            }
        }
        else  {
            fprintf(stderr, "Search failed for %s\n", key[i]);
            return 1;
        }
    }

    symTable_destroy(charTable);
    symTable_destroy(intTable);
    symTable_destroy(floatTable);
    symTable_destroy(double_arrayTable);
    return 0;
}

頭文件還包括以下結構:

typedef struct SymTable *SymTable_T;

我目前的輸出是這樣,如您所見,這些值完全錯誤,我不確定原因。 我認為問題出在我有關內存的插入函數中,但是我不確定:

我的輸出:

Creating symbol table with character values
-------------------------------------------
Insert <Einstein, e>
Insert <Newton, n>
Insert <Bohr, b>
Insert <Curie, c>

Creating symbol table with integer values
-----------------------------------------
Insert <Einstein, 10>
Insert <Newton, 20>
Insert <Bohr, 30>
Insert <Curie, 40>

Creating symbol table with float values
---------------------------------------
Insert <Einstein, 1.11>
Insert <Newton, 2.22>
Insert <Bohr, 3.33>
Insert <Curie, 4.44>

Creating symbol table with arrays of two double values
------------------------------------------------------
Insert <Einstein, [1.11, 2.22]>
Insert <Newton, [3.33, 4.44]>
Insert <Bohr, [5.55, 6.66]>
Insert <Curie, [7.77, 8.88]>

Searching symbol table with character values
--------------------------------------------
Einstein found, value = \300: now deleting
Newton found, value = \340: now deleting
Bohr found, value = : now deleting
Curie found, value = : now deleting

Searching symbol table with integer values
------------------------------------------
Einstein found, value = 1070416: now deleting
Newton found, value = 1070448: now deleting
Bohr found, value = 1071472: now deleting
Curie found, value = 0: now deleting

Searching symbol table with float values
----------------------------------------
Einstein found, value = 1.50248e-39: now deleting
Newton found, value = 1.50253e-39: now deleting
Bohr found, value = 1.50257e-39: now deleting
Curie found, value = 0: now deleting

Searching symbol table with arrays of two double values
-------------------------------------------------------
Einstein found, value = [2.12253e-314, 2.22]: now deleting
Newton found, value = [2.12253e-314, 4.44]: now deleting
Bohr found, value = [2.12253e-314, 6.66]: now deleting
Curie found, value = [0, 8.88]: now deleting

正確的輸出應為:

Creating symbol table with character values
-------------------------------------------
Insert <Einstein, e>
Insert <Newton, n>
Insert <Bohr, b>
Insert <Curie, c>

Creating symbol table with integer values
-----------------------------------------
Insert <Einstein, 10>
Insert <Newton, 20>
Insert <Bohr, 30>
Insert <Curie, 40>

Creating symbol table with float values
---------------------------------------
Insert <Einstein, 1.11>
Insert <Newton, 2.22>
Insert <Bohr, 3.33>
Insert <Curie, 4.44>

Creating symbol table with arrays of two double values
------------------------------------------------------
Insert <Einstein, [1.11, 2.22]>
Insert <Newton, [3.33, 4.44]>
Insert <Bohr, [5.55, 6.66]>
Insert <Curie, [7.77, 8.88]>

Searching symbol table with character values
--------------------------------------------
Einstein found, value = e: now deleting
Newton found, value = n: now deleting
Bohr found, value = b: now deleting
Curie found, value = c: now deleting

Searching symbol table with integer values
------------------------------------------
Einstein found, value = 10: now deleting
Newton found, value = 20: now deleting
Bohr found, value = 30: now deleting
Curie found, value = 40: now deleting

Searching symbol table with float values
----------------------------------------
Einstein found, value = 1.11: now deleting
Newton found, value = 2.22: now deleting
Bohr found, value = 3.33: now deleting
Curie found, value = 4.44: now deleting

Searching symbol table with arrays of two double values
-------------------------------------------------------
Einstein found, value = [1.11, 2.22]: now deleting
Newton found, value = [3.33, 4.44]: now deleting
Bohr found, value = [5.55, 6.66]: now deleting
Curie found, value = [7.77, 8.88]: now deleting

任何幫助,將不勝感激。

p = (SymTable_T)malloc(sizeof(SymTable_T)); 那是不對的。 由於SymTable_T是指針,因此它僅分配指針大小的緩沖區。 C語言中的最佳實踐是不強制轉換malloc。 所以應該是: p = malloc(sizeof *p); p = malloc(struct SymTable); –貝殼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM