2012-02-27 49 views
0

我有一個至極BST庫我存儲一些結構:ç投無效*數據typedef結構

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. 回報的一個節點,它的數據分配給模型* 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中,任何幫助,將不勝感激

+0

滾出需要投空指針的?真的嗎? – tbert 2012-02-27 11:54:28

+0

'(model *)search(root,mod);'顯然是錯誤的,您正在將'struct bst_node **'轉換爲'model *'。在第二種方法中,可能需要'if(node!= NULL &&(* node)!= NULL)'。你用方法2面臨什麼問題? – 2012-02-27 11:57:12

+0

@ another.anon.coward搜索與搜索不同,因此它返回(* node) - >數據 – 2012-02-27 12:06:39

回答

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

} 

如果不工作(請詳細介紹瞭如何的事情「不工作」解釋了),還有別的東西錯了。

你也可以改變搜索()函數只返回一個bst_node *,不得不面對一個雙指針似乎不必要在這裏

+0

如果我嘗試訪問其他屬性(如價格崩潰),則會打印另一個名稱(始終是相同的名稱) – 2012-02-27 12:15:37

+0

那麼也許在別的地方有什麼問題。例如內存損壞?一些錯誤,你建立BST? – nos 2012-02-27 12:30:03

+0

我可以添加/刪除節點沒有錯誤,所以我想錯誤是當我投的數據或水手。 – 2012-02-27 12:36:00

0

怎麼回合只是說

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

它不起作用:( – 2012-02-27 11:53:04

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);,但我不認爲它是雙指針的任何理由,所以更改其聲明爲struct bst_node* root;,以便您通過簡單的search(root, mod);調用你的函數。

+0

但這意味着修改bst容器的外部librayro修改它的所有功能,等等 – 2012-02-27 11:55:49

+0

@LucianEnache:我沒有注意到這是在外部庫。現在檢查我的答案 – LihO 2012-02-27 11:57:43

+0

@LucianEnache如果外部庫是模糊的,它應該改變,因爲它是,代碼沒有任何意義 – Lundin 2012-02-27 12:11:32