C将void *数据转换为typedef结构

时间:2012-02-27 11:41:24

标签: c pointers data-structures

我有一个BST库,我存储了一些结构:

struct bst_node {
    char *key;
    void* data;                // this one i want to get it casted to struct model
    struct bst_node* left;
    struct bst_node* right;
};

这是一个搜索函数,它返回一个驻留在bst.c中的bst_node

struct bst_node** search(struct bst_node** root,char *key) {
    struct bst_node** node = root;
    while (*node != NULL) {
        int compare_result = compare(key, (*node)->key);
        if (compare_result < 0)
            node = &(*node)->left;
        else if (compare_result > 0)
            node = &(*node)->right;
        else
            break;
    }
    return node;
}

此时我在main.c中有这个结构,它包含在void*数据中

typedef struct model_t{
    char name[MAX];
    char file_a[MAX];
    char date[MAX];
    int price;
    accesories *acs;
}model;

假设在main.c中我搜索一个项目并返回一个包含我感兴趣的void*数据的树节点,我该如何转换该数据并将其分配给模型以便稍后进行我可以访问模型的字段(例如修改附件列表)?

以下是我尝试的方式:

  1. 返回数据

    model *m;
    m  = (model *)searches(root,mod);  // the searches function is similar to the search posted
    if (m != NULL) {                   //before but instead of a node returns &(*node)->data
        printf("\n--------%s\n",(*m).name);
    
  2. 返回一个节点并将其数据分配给模型* m指针

    model* m;
    struct bst_node** node  = search(root,mod);  //return the node containing the string
                                                 //in "mod" and assign node->data to m
    if (node != NULL) {  
         m=(*node)->data;
         print_list(m);             //this functions prints the accesories list
    }
    
  3. 我确信有办法绕过这个但是我找不到任何帮助会受到高度赞赏。

    ----------------------------------------------- ------------ main.c中----------------------------------- -

        #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "bst.h"
    
    
    #define MAX 50
    
    typedef struct accesori_t{
        char nome[MAX];
        int prezzo;
        struct accesori_t *next;    
    }accesori;
    
    typedef struct modello_t{
        char nome[MAX];
        char file_a[MAX];
        char date[MAX];
        int prezzo;
        accesori *acs;
    }modello;
    
    
    
    void stampa_lista(struct modello_t *m);
    void append_node(struct accesori_t *llist,char *nome, int prezzo);
    void stampa_modelli(struct bst_node* root);
    void salva_lista(struct bst_node* root,char *nf);
    void inserisci_modello(struct bst_node** root);
    void cancella_modello(struct bst_node** root);
    void inserisci_acs(struct bst_node** root);
    void cancella_acs(struct bst_node** root);
    //struct modello_t *cerca_modello();
    void stampa_affinita(struct bst_node* root);
    
    int main(int argc, char *argv[])
    {
        int menu=0;
    
        char nf[MAX];
    
        char *t;
        char nome[MAX];
        char file_a[MAX];
        char data[MAX];
        int prezzo,gg,mm,a,index=0;
    
    
        int prezzo_a;
        char nomea[MAX];
        struct accesori_t *head,*curr;
        struct accesori_t *tmp;
    
    
        FILE *fp;
        FILE *fa;
        fp=fopen("cars.txt","r+");
    
        struct modello_t *m;
        m = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        struct bst_node* root=NULL;
    
    
    
        while(fscanf(fp,"%s %s %d %s",nome,data,&prezzo,file_a)!=EOF){
    
                strcpy((*m).nome,nome);
                strcpy((*m).file_a,file_a);
                strcpy((*m).date,data);
                (*m).prezzo=prezzo;
                //printf("%s\n",(*m).nome);                  
    
                fa=fopen((*m).file_a,"r+");
    
    
                m->acs=(struct accesori_t *)malloc(sizeof(struct accesori_t));
                while(fscanf(fa,"%s %d",nomea,&prezzo_a)!=EOF)
                {                   
                    append_node(m->acs,nomea ,prezzo_a);       
                    while(m->acs->next != NULL)
                        {
                            m->acs = m->acs->next;
                            //printf("\t%s --- %d\n",m->acs->nome,m->acs->prezzo);
    
                        }
                }
    
                insert(&root, m->nome, m);   
                close(fa);
    
        }
    
        while(1){
    
            printf("\n\t1.Stampa Lista modelli");  
            printf("\n\t2.Inserisci nuovo modello");
            printf("\n\t3.Cancella un modello");
            printf("\n\t4.Inserisci Accesorio");
            printf("\n\t5.Cancella Accesorio");
            printf("\n\t6.Salva la lista");
            printf("\n\t7.Stampa Affinita'");
            printf("\n\t0.EXIT");
            printf("\n\t"); 
            printf("\nINSERIRE SCELTA : ");
            scanf("%d",&menu);   
    
            switch(menu)
            {
                case 1:
                    stampa_modelli(root);
                    break;
    
                case 2:
                    inserisci_modello(&root);
                    break;
                case 3:
                    cancella_modello(&root);
                    break;
                case 4:
                    inserisci_acs(&root);
                    break;
                case 5:
                    cancella_acs(&root);
                    break;
                case 6:
                    salva_lista(root,nf);
                    break;
                case 7:
                    stampa_affinita(root);
                    break;
                case 0:
                    return;
    
            }
    
        }  
    
    
    
    
      delete_tree(root);
      close(fp);
      system("PAUSE");  
      return 0;
    }
    
    void append_node(struct accesori_t *llist,char *nome, int prezzo) {
        while(llist->next != NULL)
            llist = llist->next;
    
        llist->next = (struct accesori_t *)malloc(sizeof(struct accesori_t));
        llist->next->prezzo = prezzo;
        strcpy( llist->next->nome,nome);
        llist->next->next = NULL;
    }
    
    void stampa_lista(struct modello_t *m){
        while(m->acs->next != NULL)
        {
            m->acs = m->acs->next;
            printf("\t%s --- %d\n",m->acs->nome,m->acs->prezzo);
    
        }
    }
    
    void stampa_modelli(struct bst_node* root){
            preorder_traverse(root);
    }
    
    void inserisci_modello(struct bst_node** root){
    
        FILE *fa;
        struct modello_t *temp;
        char nomea[MAX];
        int prezzo_a;
        temp = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        printf("\nInserire il nome : ");
        scanf("%s",temp->nome);
    
        printf("\nInserire il file degli accesori : ");
        scanf("%s",temp->file_a);
    
        printf("\nInserire la data di disponibilita' (gg/mm/aaaa) : ");
        scanf("%s",temp->date);
    
        printf("\nInserire il prezzo : ");
        scanf("%s",&temp->prezzo);
    
    
        printf("%s\n",(*temp).nome);                 
        fa=fopen(temp->file_a,"r");
    
    
                temp->acs=(struct accesori_t *)malloc(sizeof(struct accesori_t));
                while(fscanf(fa,"%s %d",nomea,&prezzo_a)!=EOF)
                {                   
                    append_node(temp->acs,nomea ,prezzo_a);       
                    while(temp->acs->next != NULL)
                        {
                            temp->acs = temp->acs->next;                                               
                        }
                } 
                insert(root, temp->nome, temp);   
    
        free(temp);
        close(fa);   
    }
    
    void cancella_modello(struct bst_node** root){
    
        char mod[MAX];
    
        printf("\nInserire il nome del modello da cancellare : ");
        scanf("%s",mod);
    
        struct bst_node** node = search(root,mod);
    
        if (*node != NULL) {
            delete(node);
        }
    
        preorder_traverse((*root));    
        free(node);       
    }
    void inserisci_acs(struct bst_node** root){
        char mod[MAX];
        char acs[MAX];
        int prezzo_a;
    
        //struct modello_t* m;
    
        printf("\nInserire il nome del modello: ");
        scanf("%s",mod);
    
        struct modello_t **r = searches(root,mod);
    
        struct modello_t *m = *r; 
        if(m != NULL) { 
            printf("\n--------%s\n",m->nome); 
        } 
    
        //struct modello_t *m;
        //m  = (struct modello_t *)searches(root,mod); //trovare come fare a far ritornare il void *data
    
        /*if (m != NULL) {
            printf("\n\nQuesto pezzo di programma e' ancora da rivedere in quanto ho dei problemi\n nel convertire void* data in struct modello\n\n" );
    
    
            //m=(*node)->data; // parte problematica
            //stampa_lista(m);
            printf("\n--------%s\n",(*m).file_a);
            printf("\nInserire il nome dell'accesorio da aggiungere: ");
            scanf("%s",acs);
            printf("\nInserire il prezzo dell'accesorio da aggiungere: ");
            scanf("%s",prezzo_a);
    
            while(m->acs->next != NULL)
            {
                m->acs = m->acs->next; 
                if(m->acs->next == NULL)
                    append_node(m->acs,acs ,prezzo_a);                                                   
            }
    
        }*/
        free(m);    
    
    }
    void cancella_acs(struct bst_node** root){
        char mod[MAX];
        char acs[MAX];
    
    
        //struct modello_t *m;
    
        printf("\nInserire il nome del modello: ");
        scanf("%s",mod);
    
        struct bst_node **node  = search(root,mod);
    
        if(*node == NULL) 
        { 
            puts("Not found"); 
        } else { 
            struct modello_t *m = (*node)->data; 
    
        if(m == NULL) 
        { 
            puts("Found, but data is NULL"); 
        } else { 
            printf("\n--------%s\n",m->nome); 
        } 
        }
    
        /*if (node != NULL) {
            printf("\nQuesto pezzo di programma e' ancora da rivedere in quanto\n ho dei problemi nel convertire void* data in struct modello\n" );
    
    
        m=(struct modello_t*)((*node)->data); // parte problematica
    
         printf("\n--------%s\n",m->prezzo);
        //stampa_lista(m);
    
        printf("\nInserire il nome dell'accesorio da cancellare: ");
        scanf("%s",acs);
    
    
             while(m->acs->next != NULL)
            {   
                if(strcmp(m->acs->next->nome, acs)){
                    if(m->acs->next->next==NULL)
                       m->acs->next==NULL;        
                    m->acs->next=m->acs->next->next;
                    break; 
                } 
                m->acs = m->acs->next; 
    
            }
        }*/
        free(node);   
    }
    
    void salva_lista(struct bst_node* root,char *nf){
        FILE *fp;
        FILE *fa;
        fp=fopen(nf,"w+");
        char na[MAX];
    
        struct modello_t *m;
        //m = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        /*while(ritorna_nodi(root)) 
        {       m=ritorna_nodi(root)
    
                fprintf(fp,"%s %s %d %s",(*m).nome,(*m).date,(*m).prezzo,(*m).file_a);                              
                fa=fopen((*m).file_a,"w+"); 
    
                while(m->acs->next!=NULL)
                {                   
                    fprintf(fp,"%s %d ",m->acs->nome,m->acs->prezzo);
                    m->acs=m->acs->next;
                }
                close(fa);               
        }*/
        close(fp);  
    }
    stampa_affinita(struct bst_node* root)
    {
          stm_aff(root);   
    }
    

    ----------------------------------------------- ---- bst.c ------------------------------------------- -

    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    #include "bst.h"
    #include "data.h"
    
    
    struct bst_node* new_node(char *key,void* data) 
    {
        struct bst_node* result = malloc(sizeof(struct bst_node));
        assert(result);
        result->data = data;
        result->key=malloc(strlen(key)*(sizeof(char)));
        strcpy(result->key,key);
        result->left = result->right = NULL;
        return result;
    }
    
    int compare(void* left,void* right)
    {
        if (strcmp(left,right)<0)
        {
            return -1;
        }
        else if (strcmp(left,right)==0)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    
    
    
    void free_node(struct bst_node* node) 
    {
        assert(node);
        free(node);
        node = NULL;
    }
    
    struct bst_node** search(struct bst_node** root,char *key) {
        struct bst_node** node = root;
        while (*node != NULL) {
            int compare_result = compare(key, (*node)->key);
            if (compare_result < 0)
                node = &(*node)->left;
            else if (compare_result > 0)
                node = &(*node)->right;
            else
                break;
        }
        return node;
    }
    
    void* searches(struct bst_node** root,char *key) {
        struct bst_node** node = root;
        while (*node != NULL) {
            int compare_result = compare(key, (*node)->key);
            if (compare_result < 0)
                node = &(*node)->left;
            else if (compare_result > 0)
                node = &(*node)->right;
            else
                break;
        }
        return (*node)->data;
    }
    
    void insert(struct bst_node** root,char *key, void* data) {
        struct bst_node** node = search(root,key);
        if (*node == NULL) {
            *node = new_node(key,data);
        }
    }
    
    void delete(struct bst_node** node) {
        struct bst_node* old_node = *node;
        if ((*node)->left == NULL) {
            *node = (*node)->right;
            free_node(old_node);
        } else if ((*node)->right == NULL) {
            *node = (*node)->left;
            free_node(old_node);
        } else {
            struct bst_node** pred = &(*node)->left;
        while ((*pred)->right != NULL) {
            pred = &(*pred)->right;
        }
        /* Swap values */
        void* temp = (*pred)->key;
        void* temp1 = (*pred)->data;
    
        (*pred)->data = (*node)->data;
        (*pred)->key = (*node)->key;
    
        (*node)->data = temp;
        (*node)->key = temp1;
    
        delete(pred);
        }
    }
    
    void visit(struct bst_node* node)
    {
        printf("%s\n", node->key);
    }
    
    void preorder_traverse(struct bst_node* root)
    {
        if (!root) return;
    
        visit(root);
        preorder_traverse(root->left);
        preorder_traverse(root->right);
    }
    
    void inorder_traverse(struct bst_node* root)
    {
        if (!root) return;
    
        inorder_traverse(root->left);
        visit(root);
        inorder_traverse(root->right);
    }
    
    void postorder_traverse(struct bst_node* root)
    {
            if (!root) return;
    
            postorder_traverse(root->left);
            postorder_traverse(root->right);
            visit(root);
    }
    
    void delete_tree(struct bst_node* root)
    {
        if (!root) return;
    
        delete_tree(root->left);
        delete_tree(root->right);
    
        free_node(root);
    }
    void*  ritorna_nodi(struct bst_node* root){
    
        if (!root) return;
    
        ritorna_nodi(root->left);    
        return root->data;  
        ritorna_nodi(root->right);      
    }
    void stm_aff(struct bst_node* root) // visita preorder quindi per ogni nodo visitato stampa la sua lista
    {
        if (!root) return;
    
        //stm_vst(root);
        stm_aff(root->left);
        stm_aff(root->right);
    }
    /*void stm_vst(struct bst_node* root) // dovrebbe ritornare una lista di accesori di quel nodo
    {
       return; 
    }*/
    

    ----------------------------------------------- ------------ bst.h ----------------------------------- -

    #ifndef _BST_H_
    
    struct bst_node {
        char *key;
        void* data;
        struct bst_node* left;
        struct bst_node* right;
    };
    
    struct bst_node* new_node(char *key,void* data);
    
    void free_node(struct bst_node* node);
    typedef int my_comparator(void* left, void* right);
    
    
    
    struct bst_node** search(struct bst_node** root,char *key);
    void insert(struct bst_node** root,char *key, void* data);
    void delete(struct bst_node** node);
    void preorder_traverse(struct bst_node* root);
    void inorder_traverse(struct bst_node* root);
    void postorder_traverse(struct bst_node* root);
    void delete_tree(struct bst_node* root);
    
    #endif
    

    所以我遇到麻烦的部分是main.c中的评论,非常感谢任何帮助

3 个答案:

答案 0 :(得分:1)

您的search函数返回struct bst_node**,无法将其转换为struct model_t*。此函数的返回类型应为struct model_t*,我应该return (*node)->data;

另请注意,没有理由将struct bst_node**传递给此功能。改为通过struct bst_node*。如果root被声明为struct bst_node**,那么就像这样调用你的函数:search(*root, mod);,但我没有看到任何理由将它作为双指针,因此将其声明更改为{{1因此,您可以通过简单的struct bst_node* root;调用您的函数。

答案 1 :(得分:1)

你这样做:

struct bst_node **r = search(root,mod);
if(*r == NULL) {

  puts("Not found");

} else {

  model_t *m = (*r)->data;
  if(m == NULL) {
     puts("Found, but data is NULL");
  } else {
     printf("\n--------%s\n",m->name);
  }

}

如果这不起作用(请详细解释“事情不起作用”),还有其他问题。

您还可以将search()函数更改为仅返回bst_node *,此处不得不处理双指针

答案 2 :(得分:0)

怎么回事?

m = (struct model_t*)((*node)->data);