简体   繁体   English

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

[英]C cast void* data to typedef struct

I have a BST library in wich I store some structs : 我有一个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;
};

Here is the search function that returns me a bst_node that resides in bst.c: 这里是返回我的搜索功能bst_node驻留在bst.c:

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;
}

At this point I'm having in main.c this struct wich is contained in the void* data 此时我在main.c中有这个结构,它包含在void*数据中

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

Suppose that in main.c I search for an item and get returned a tree node containing the void* data that I'm interested in, how can I cast that data and assign it to a model so later on I can access the fields of model (for example modify the accesories list) ? 假设在main.c中我搜索一个项目并返回一个包含我感兴趣的void*数据的树节点,如何转换该数据并将其分配给模型以便稍后我可以访问模型(例如修改配件清单)?

Here are the ways I tried : 以下是我尝试的方法:

  1. return the data 返回数据

     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. return a node and assign it's data to the model *m pointer 返回一个节点并将其数据分配给model * 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 } 

I am certain there is a way to go around this but I just can't find it any help would be highly appreciated. 我确信有办法解决这个问题,但我无法找到任何帮助,我将非常感激。

-----------------------------------------------------------main.c------------------------------------ -------------------------------------------------- --------- 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--------------------------------------------- -------------------------------------------------- -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------------------------------------- -------------------------------------------------- --------- 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

So the pieces I'm having trouble with are the commented ones in main.c, any help would be greatly appreciated 所以我遇到麻烦的部分是main.c中的评论,任何帮助都将不胜感激

Your search function returns struct bst_node** which can't be casted to struct model_t* . 您的search函数返回struct bst_node** ,它无法转换为struct model_t* Return type of this function should be struct model_t* and you should return (*node)->data; 这个函数的返回类型应该是struct model_t* ,你应该return (*node)->data; I guess. 我猜。

Also note that there is no reason to pass struct bst_node** to this function. 另请注意,没有理由将struct bst_node**传递给此函数。 Pass struct bst_node* instead. 传递struct bst_node* If root is declared as struct bst_node** then call your function like this: search(*root, mod); 如果root被声明为struct bst_node**那么就像这样调用你的函数: search(*root, mod); , but I don't see any reason for it to be double pointer, so change its declaration to struct bst_node* root; ,但我没有看到任何理由将它作为双指针,所以将其声明更改为struct bst_node* root; so that you call your function by simple search(root, mod); 这样你就可以通过简单的search(root, mod);调用你的函数search(root, mod); .

You'd do this: 你这样做:

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);
  }

}

If that does not work(please explain in detail how things "doesn't work"), there is something else wrong. 如果这不起作用(请详细解释“事情不起作用”),还有其他错误。

You could also change the search() function to just return a bst_node* , having to deal with a double pointer seems unneccessary here 你也可以改变search()函数只返回一个bst_node *,这里不得不处理双指针似乎是不必要的

怎么回事呢

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM