im currently making a project for a college work and while doing it i came across that error and i have no clue what is causing it.
The line it points to is : if ((*compara)(ptr->dados, valor))
The Function :
void * pesquisar(PNO cabeca, int (*compara)(), void* valor) {
PNO ptr;
for (ptr = cabeca; ptr; ptr = ptr->prox);
if ((*compara)(ptr->dados, valor))
return ptr->dados;
return NULL;
}
The Structs
struct no{
struct no*prox;
struct no*ant;
void *dados;
};
typedef struct no NO;
typedef NO*PNO;
typedef NO**PPNO;
struct cliente{
int ID_cliente;
char nome[60];
char morada[255];
int contribuinte;
struct cliente * prox;
};
typedef struct cliente CLIENTE;
typedef CLIENTE*PCLIENTE;
CLIENTE *cabCliente, *cauCliente;
The Main :
PNO Cliente = NULL, Fatura = NULL;
PCLIENTE pesquisa;
char n;
void * Dados;
int opcao;
char nome[60];
case 3:
printf("Insira o Nome: ");
fgets(nome, 60, stdin);
nome[strlen(nome) - 1] = '\0';
pesquisa = pesquisar(Cliente, cmpNomeCliente, nome);
if (pesquisa) printf("Nome é: %s", nome);
else printf("Aluno inexistente");
getch();
break;
for (ptr = cabeca; ptr; ptr = ptr->prox);
if ((*compara)(ptr->dados, valor))
In this sequence of code, ptr in the second line will always be NULL because the for loop runs until the ptr expression is false and due to the ; after the for, the loop has no body.
Related
This question already has answers here:
typedef struct vs struct definitions [duplicate]
(12 answers)
Why should we typedef a struct so often in C?
(15 answers)
Closed 3 months ago.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
char nome[40];
char telefone[15];
char celular[15];
char email[40];
struct pessoa *prox;
} pessoa;
pessoa * criarLista(){
return NULL;
}
pessoa * inserir(pessoa *lista,char nome[40],char telefone[15],char celular[15],char email[40]){
pessoa *novo = (pessoa *) malloc(sizeof(pessoa));
strcpy(novo -> nome, nome);
strcpy(novo -> telefone, telefone);
strcpy(novo -> celular, celular);
strcpy(novo -> email, email);
novo -> prox = lista;
return novo;
}
pessoa * busca(pessoa*lista,char nome[40]){
pessoa *p = lista;
while(p!=NULL){
if (strcmp(nome,p->nome) == 0){
return p;
}
else{
p = p->prox;
}
}
return NULL;
}
void exibir(pessoa * lista){
pessoa *p = lista;
while(p!=NULL){
printf("\n%s",p->nome);
printf("%s",p->email);
printf("%s",p->telefone);
printf("%s",p->celular);
p = p->prox;
}
}
pessoa* remover(pessoa **lista, char nome[40]){
pessoa *aux, *remover = NULL;
if(*lista){
if(strcmp((*lista)->nome,nome) == 0){
remover = *lista;
*lista = remover->prox;
}
else{
aux = *lista;
while(aux->prox && strcmp(aux->prox->nome,nome)!= 0){
aux = aux->prox;
if(aux->prox){
remover = aux->prox;
aux->prox = remover->prox;
}
}
}
}
return remover;
}
int main(void){
char nome[40];
char telefone[15];
char celular[15];
char email[40];
pessoa *lista = (pessoa *) malloc(sizeof(pessoa));
pessoa *b = (pessoa *) malloc(sizeof(pessoa));
lista = criarLista();
b=criarLista();
int op;
while (op!=5){
printf("\n1- inserir contato \n2- listar contatos \n3- buscar contatos \n4- deletar contato\n5- sair\n");
scanf("%d", &op);
setbuf(stdin, NULL);
switch (op) {
case 1:
printf("Digite o nome: ");
fgets(nome,sizeof(nome),stdin);
printf("Digite o email: ");
fgets(email,sizeof(email),stdin);
printf("Digite o telefone: ");
fgets(telefone,sizeof(telefone),stdin);
printf("Digite o celular: ");
fgets(celular,sizeof(celular),stdin);
lista=inserir(lista,nome,telefone,celular,email);
break;
case 2:
exibir(lista);
break;
case 3:
printf("Digite o nome que deseja buscar: ");
fgets(nome,sizeof(nome),stdin);
b = busca(lista,nome);
if (b != NULL){
printf("%s",b->nome);
printf("%s",b->email);
printf("%s",b->telefone);
printf("%s\n",b->celular);
}
else{
printf("Contato não encontrado!");
}
break;
case 4:
printf("Digite o nome do contato que deseja excluir: ");
fgets(nome,sizeof(nome),stdin);
lista = remover(&lista,nome);
}
}
return 0;
}
Tried to put an array that creates a new knot, list all of them, search and remove. But when i was trying to make the remove function, something went wrong and i cound't proceed.The error was aparrently in the function remover, a "incomplete definition of type 'struct pessoa'" error, what is strange cause my typedef struct (prox) works in all of the others functions.
Can someone please help me?
You have:
typedef struct {
char nome[40];
char telefone[15];
char celular[15];
char email[40];
struct pessoa *prox;
} pessoa;
You've defined an untagged structure type called pessoa; you have not defined a type struct pessoa. This is legitimate, but not what you wanted.
The fix is simple:
typedef struct pessoa
{
char nome[40];
char telefone[15];
char celular[15];
char email[40];
struct pessoa *prox;
} pessoa;
Now you have both a struct pessoa and (after this typedef is complete), a type name pessoa.
Background
As noted, the notation used in the question's code is legitimate, but not what you wanted. For self-referential structures like you want, you have to use a tag. You could use:
typedef struct pessoa pessoa;
struct pessoa
{
char nome[40];
char telefone[15];
char celular[15];
char email[40];
pessoa *prox; // struct not needed, though still valid
};
Being able to reference struct tagname without defining what's in the structure allows you to have 'opaque types' where client code can
only use pointers to the type, and only the implementation functions can see the internals of the type. This is often beneficial as a way of hiding information.
Note that the language makes no requirement that the tag name and the typedef name are related in any way. However, it is conventional and sensible to make sure that the tag names and the typedef names are, in fact, related, so it is easier for people reading the code. Note that tag names are in a separate namespace from typedef names.
I wrote a function to delete and extract an Item from a list following the usual algorithm for extraction, but while it scans the list it deletes all the items before the searched element.
I am probably missing some pointer being dereferenced but I can't really see where...
Thank you in advance for the help.
Here's the full code.
//DATA STRUCTURE
typedef struct{//EQUIPMENT
int inUse;
object **arrEquip;
}equip;
typedef struct{//PG
char code[MAXL];
char name[MAXL];
char class[MAXL];
equip equip_t;
stats stats_t;
}pg;
typedef struct nodePg theNodePg, *link;
struct nodePg{ //NODE
pg pg_t;
link next;
};
typedef struct{//LIST WRAPPER
link head;
link tail;
int nPg;
}tabPg;
int main(){
tabPg tabPg_t;
tabInv tabInv_t;
int choice;
tabPg_t.head = NULL;
tabPg_t.nPg = 0;
do{
printMenu(&choice);
runSelectedFun(&tabPg_t, &tabInv_t, choice);
}while(choice != 0);
return 0;
}
void runSelectedFun(tabPg *tabPg_t, tabInv *tabInv_t, int choice){
//[...]
pgExtraction(&tabPg_t->head);
//[...]
}
void pgExtraction(link *head){//eliminarlo dalla lista effettivamente
char toBeDeleted[MAXL];
theNodePg deleted;
int flag = 0;
printf("\nInserisci il codice del personaggio da eliminare");
scanf("%s", toBeDeleted);
deleted = extraction(head, toBeDeleted, &flag);
if(flag == 1){
printf("\nPersonaggio %s eliminato con successo!", deleted.pg_t.code);
}
else printf("\nIl codice inserito non ha corrispondenze all'interno della lista PG!\n");
}
theNodePg extraction(link *head, char *code, int *flag){
link *xp,t;
theNodePg deletedPg = {0};
for (xp = head; xp != NULL; xp = &(*xp)->next) {
if (strcmp((*xp)->pg_t.code, code) == 0) {
t = (*xp);
*xp = (*xp)->next;//eliminazione
deletedPg = *t;
free(t);
*flag = 1;
break;
}
}
return deletedPg;
}
I'm having troubles passing by working on a list with "int" keys to a "char *" keys.
the struct looks like :
struct nodo {
char *info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
and I'm trying to use a function i used a lot to fill a struct with int or float fields (adapted obviously):
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
assert(n!=0);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%c" /* or maybe s? i need a string for each nodo... */, p->info);
// i feel this is the line that needs some more work
p->prec = back;
p->succ = NULL;
if (p->prec)
p->prec->succ = p;
back = p;
}
primo = p;
while (primo != NULL && primo->prec != NULL)
primo = primo->prec;
return primo;
}
Any suggestions?
Just add & in scanf in the line you mentioned,
scanf(" %c", &p->info);
and give a space before %c in format string to " %c" so that it display text in format you want.
Hello guys i got a problem while running this code:
trying to run the printf in the comment i got a segfault, also without that i dont see my listed printed ad the function Stampa should do.
Probably i am missing something with pointers
#include <stdio.h>
#include <stdlib.h>
struct nodo { // double linked list
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
// printf("%d",p->succ->info);
Stampa(p);
return 0;
}
// this funct should print the whole list
void Stampa (struct nodo *p) {
while (p->succ != NULL ) {
printf("Value : %d \n", p->info);
p = p->succ;
}
}
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
Stampa()
Let's look at what we want to do when we print the entire list:
If the current element is valid, then we want to print it.
Then, we want to iterate to the next element, and continue this loop.
That's not what your code does. Your code looks to see if the current element has a successor, and if it does, we print the current element's value.
That function should actually be:
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d\n", p->info);
p = p->succ;
}
}
Crealista()
If you tell Crealista() to create a list of 0 elements, your final while loop will exhibit undefined behavior.
If you tell Crealista() to create a list of less than 2 elements, your commented printf() in main() will cause undefined behavior (if it was uncommented).
Doubly Linked Lists
You never update the value of nodo->succ. You only update the value of nodo->prev. Here's one example of how to do that:
if (p->prec)
p->prec->succ = p;
Putting all of this together
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
Stampa(p);
}
// Print the list
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d \n", p->info);
p = p->succ;
}
}
// Create a list of n elements
struct nodo *Crealista(void) {
int i, n;
struct nodo *p = NULL;
struct nodo *primo = NULL;
struct nodo *back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
assert(n != 0);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
if (p->prec)
p->prec->succ = p;
back = p;
}
primo = p;
while (primo != NULL && primo->prec != NULL)
primo = primo->prec;
return primo;
}
Which when run...
Numero di elementi: 5
inserisci 5 numeri interi positivi: 1 2 3 4 5
Value: 1
Value: 2
Value: 3
Value: 4
Value: 5
The printf() call you have commented out will always exhibit undefined behavior when p->succ is NULL, as it will be when p points to the last (or only) element of the list. In that case, although the behavior is formally "undefined", it is quite likely to manifest as a segmentation fault.
In stampa add check
while(p!=NULL)
{
printf("Value %d",p->info);
p=p->succ;
}
You are probably accessing it when it is not allocated. Check it this way there is no problem if it reaches a null value also. And initial null value will not cause problem also(if used).
I have modified your code
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
for (i=1; i<n; i++) {
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->prec->succ=p;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
You are not setting the succ pointer of previous node correctly. That is what causing you the problem. Check now.
My goal is to create a list from "menu.bin". This is the func:
pitem recupera_menu(pitem p){
pitem novo,aux;
FILE *f;
f=fopen("menu.bin","rb");
if(f == NULL)
printf("Erro ao caregar o ficheiro 'menu.bin' \n");
novo = (struct item*)malloc(sizeof(item));
if(novo == NULL)
return p;
novo->prox=NULL;
while((fread(novo,sizeof(item),1,f))!=NULL){
if(p==NULL){
p=novo;
aux=p;
}
else{
aux->prox=novo;
aux=aux->prox;
}
printf("%s\n OLE\n",aux->id);
}
fclose(f);
system("pause");
return p;
}
this is my struct:
typedef struct item item, *pitem;
struct item{
char id[5];
int ing[10];
float qtd[10];
pitem prox;
};
For some reason the result of the file isn't the one that should be(it doesn't read the document strait).Maybe someone could help me.
EDIT:
well it does run, and prints the "ole" line.The problem is that the file .bin has been completed with the following struct type:
struct item{
char id[5];
int ing[10];
float qtd[10];}
and when i do malloc, i allocate memory to the folowing struct type:
struct item{
char id[5];
int ing[10];
float qtd[10];
pitem prox;
};
struct item{
char id[5];
int ing[10];
float qtd[10];
};
struct list{
struct list *next;
struct item payload;
};
Allocate:
struct list *p;
p = malloc (sizeof *p);
read from file:
ret = fread(&p->payload, sizeof p->payload, 1, fp);
Extra: sanitize the loop:
int recupera_menu(struct list **pp){
int ret,cnt;
FILE *fp;
fp = fopen("menu.bin","rb");
if (!fp) {
fprintf(stderr, "Erro ao caregar o ficheiro 'menu.bin' \n");
return 0;
}
for (cnt=0; ;cnt++) {
*pp = malloc(sizeof **pp);
if( !*pp ) break;
(*pp)->next = NULL;
ret = fread(&(*pp)->payload, sizeof &(*pp)->payload, 1, fp);
if (ret < 1) break;
pp = &(*pp)->next;
}
free (*pp);
*pp = NULL;
fclose(fp);
return cnt
}