簡體   English   中英

C將void *數據轉換為typedef結構

[英]C cast void* data to typedef struct

我有一個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_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;
}

此時我在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. 返回一個節點並將其數據分配給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 } 

我確信有辦法解決這個問題,但我無法找到任何幫助,我將非常感激。

-------------------------------------------------- --------- 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中的評論,任何幫助都將不勝感激

您的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); ,但我沒有看到任何理由將它作為雙指針,所以將其聲明更改為struct bst_node* root; 這樣你就可以通過簡單的search(root, mod);調用你的函數search(root, mod);

你這樣做:

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 *,這里不得不處理雙指針似乎是不必要的

怎么回事呢

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

暫無
暫無

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

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