запрос на членство '' в чем-то, не являющемся структурой или объединением - PullRequest
0 голосов
/ 03 марта 2012

Следующий код дает мне следующие ошибки:

error: request for member ‘name’ in something not a structure or union
error: request for member ‘name’ in something not a structure or union
error: request for member ‘data’ in something not a structure or union
error: request for member ‘next’ in something not a structure or union

Как я могу это исправить?Код:

#define SIZE 5

typedef struct hashTable{
    int data;
    char *name;
    struct hashTable *next;
} table;


int hash_function(int value)
{
    return value % SIZE;
}

int insert(char *inFileName, table ***hashLinked)
{
    FILE *inFile;
    int val = -1;
    char str[30];
    int probe;

    if ((inFile = fopen(inFileName, "r")) == NULL)
    {
        fprintf(stderr,"Error opening input file, %s\n", inFileName);
        return -1;
    }
    while(fscanf(inFile,"%s %d",str,&val) == 2)
    {
        probe = hash_function(val);

        if(hashLinked[probe] == NULL)
        {                             
            **hashLinked[probe] = malloc(sizeof(table));   
            **hashLinked[probe]->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
            strcpy(**hashLinked[probe]->name,str);

            **hashLinked[probe]->data = val;
            **hashLinked[probe]->next = NULL;
        }                                             
        else
        {   
            table* hashLinkedNode = *hashLinked[probe];
            while(hashLinkedNode->next!=NULL)
            {                           
                hashLinkedNode = hashLinkedNode->next;
            }
            hashLinkedNode->next = malloc(sizeof(table));   
            hashLinkedNode->next->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
            strcpy(hashLinkedNode->next->name,str);  
            hashLinkedNode->next->data = val;
            hashLinkedNode->next->next = NULL;
        }
    } 
    fclose(inFile);
    return 0;
}


void printList(BookNode *hd)
{   
    for ( ; hd != NULL; hd = hd->next)
    {
        printf("[%s,%d]", hd->name, hd->isbn);
        if (hd->next)
            printf(" -> ");
    }
    printf("\n");
}

void printHashTable(BookNode **temp)
{
    BookNode *tmp = NULL;
    int i;
    for(i=0;i<SIZE;i++)
    {
        tmp = temp[i];
        while(tmp)
        {
            printf("%s %d",tmp->name, tmp->isbn);
            tmp=tmp->next;
        }
    }   
}

int main(int argc, char *argv[])
{
    table **hashLinked[SIZE];
    insert(argv[1],&hashLinked);
    printHashTable(**hashLinked);

    return 0;
}

1 Ответ

2 голосов
/ 04 марта 2012

Одна проблема заключается в том, что вы вызываете insert с чем-то отличным от типа, который вы объявили,

table **hashLinked[SIZE];
insert(argv[1],&hashLinked);

hashLinked - это массив указателей на указатели на table, поэтому &hashLinked - это указатель на массив указателей на указатели на table, но объявлено, что insert принимает указатель на указатель на указатель на table. Я менее чем уверен, что действительно понял, что вы намеревались сделать, но что кажется разумным, так это то, что вам нужно меньше уровней косвенности. Я считаю, что причина передачи &hashLinked состоит в том, что вы хотите, чтобы hashLinked был изменен в insert, но это уже делается путем передачи самого hashLinked, вам не нужно передавать его адрес. Это сделало бы передаваемый тип совместимым с объявленным типом, поскольку в качестве аргумента функции hashLinked становится указателем на его первый элемент, table ***.

Затем вы используете непоследовательные значения косвенности в insert и неправильно получаете приоритет * и ->, что приводит к ошибкам «запрос члена в чем-то, что не является структурой или объединением». **hashLinked[probe]->name анализируется **(hashLinked[probe]->name), поэтому пытается получить доступ к name члену table * и затем разыменовывать его дважды. С параметром типа table *** правильный доступ будет (*hashLinked[probe])->name, получим table ** за hashLinked[probe], разыменование, чтобы один раз получить table * и получить доступ к его (pointee) члену name. Тем не менее, вы проверяете if (hashLinked[probe] == NULL), и если так

**hashLinked[probe] = malloc(sizeof(table));

, что является гарантированной разыменовкой нулевого указателя. Благодаря проверке и следующему коду, я считаю, что вы действительно хотите иметь тип параметра table **, параметр hashLinked представляет собой массив связанных списков table s, что значительно упрощает выполнение кода. Заполняя тип BookNode и адаптируя несколько переменных и параметров, я получаю

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

#define SIZE 5

typedef struct hashTable {
    int data;
    char *name;
    struct hashTable *next;
} table;

typedef struct book {
    int isbn;
    char *name;
    struct book *next;
} BookNode;

int hash_function(int value)
{
    return value % SIZE;
}

int insert(char *inFileName, table **hashLinked)
{
    FILE *inFile;
    int val = -1;
    char str[30];
    int probe;

    if ((inFile = fopen(inFileName, "r")) == NULL)
    {
        fprintf(stderr,"Error opening input file, %s\n", inFileName);
        return -1;
    }
    while(fscanf(inFile,"%s %d",str,&val) == 2)
    {
        probe = hash_function(val);

        if(hashLinked[probe] == NULL)
        {
            hashLinked[probe] = malloc(sizeof(table));
            hashLinked[probe]->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
            strcpy(hashLinked[probe]->name,str);

            hashLinked[probe]->data = val;
            hashLinked[probe]->next = NULL;
        }
        else
        {
            table* hashLinkedNode = hashLinked[probe];
            while(hashLinkedNode->next!=NULL)
            {
                hashLinkedNode = hashLinkedNode->next;
            }
            hashLinkedNode->next = malloc(sizeof(table));
            hashLinkedNode->next->name = (char *)malloc((strlen(str) + 1) * sizeof(char*));
            strcpy(hashLinkedNode->next->name,str);
            hashLinkedNode->next->data = val;
            hashLinkedNode->next->next = NULL;
        }
    }
    fclose(inFile);
    return 0;
}

void printList(BookNode *hd)
{
    for ( ; hd != NULL; hd = hd->next)
    {
        printf("[%s,%d]", hd->name, hd->isbn);
        if (hd->next)
            printf(" -> ");
    }
    printf("\n");
}

void printHashTable(table **temp)
{
    table *tmp = NULL;
    int i;
    for(i = 0; i < SIZE; i++)
    {
        tmp = temp[i];
        while(tmp)
        {
            printf("%s %d",tmp->name, tmp->data);
            tmp = tmp->next;
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc < 2)
        return -1;
    table *hashLinked[SIZE];
    insert(argv[1],hashLinked);
    printHashTable(hashLinked);
    return 0;
}

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

...