C将void*数据强制转换为typedef结构
我有一个BST库,其中存储了一些结构:C将void*数据强制转换为typedef结构,c,pointers,data-structures,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\u节点: struct bst_node** search(
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\u节点
:
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*
数据的树节点,我如何转换该数据并将其分配给一个模型,以便以后可以访问模型的字段(例如修改附件列表)
以下是我尝试的方法:
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);
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
}
#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);
}
#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;
}*/
#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中的注释部分。如果您能提供任何帮助,我们将不胜感激
m = (struct model_t*)((*node)->data);
您的
search
函数返回的struct bst\u节点**
无法转换为struct model\u*
。此函数的返回类型应该是struct model\u t*
,您应该Return(*node)->data代码>我猜
还请注意,没有理由将struct bst_node**
传递给此函数。改为传递结构bst\U节点*
。如果root
被声明为struct bst\u node**
则像这样调用函数:search(*root,mod)代码>,但我看不出它是双指针的任何原因,所以将其声明更改为struct bst_node*root代码>以便通过简单的搜索(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_节点*,这里似乎不需要处理双指针摆脱强制转换空指针的需要?严重?(model*)搜索(root,mod)代码>显然是错误的,您正在将struct bst\u节点**
强制转换为model*
。在第二种方法中,如果(node!=NULL&(*node)!=NULL)
,可能需要。方法2面临什么问题?@other.anon.coward search与search不同,因此它返回(*node)->data@another.anon.coward在方法2中,我在将数据分配给m,然后访问m字段时遇到问题。非常抱歉!史诗般的视觉失败:|。。。可能是添加时出错了。。。因为很长一段时间已经过去了,希望你已经解决了你的问题或者你有了一些指针,但是这意味着要修改bst容器的外部库,修改它的所有函数等等on@LucianEnache:我没有注意到它在外部图书馆里。现在检查我的答案。@Lucianneche如果外部库不清楚,也应该更改它。实际上,代码没有任何意义。它是一个双指针,因为我也使用该函数删除节点。。。正如我所说,这应该是一个处理泛型的库types@LucianEnache不要将同一个函数用于两个不同的目的。使用不同的功能。看来这种复杂性已经很难处理了。Kernighan的名言:“调试的难度是一开始编写代码的两倍。因此,如果你尽可能巧妙地编写代码,根据定义,你就没有足够的智慧来调试它。”
它会给我另一个名字(总是相同的名字)如果我尝试访问其他属性,如price it Crash,那么可能其他地方出了问题。e、 g.内存损坏?构建BST时出现错误?我可以添加/删除节点而不会出错,因此我假设错误发生在我转换数据或smth时。@Lucian Enache否,如果您尝试上述代码,则不会。可能您没有为结构正确分配内存。可能是插入堆栈上声明的节点,可能是插入代码错误,或者是其他原因。@Lucian Enache您只分配了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);
}
}