Filling Char* in struct field (list) - c

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.

Related

Item extraction from a list in C

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

Adding a string in a node

i have a problem with adding an string type inside of a node list.
I am using the command strncpy(), but i am not sure how this works with the pointer.
This is the code block i have now.
My specific problem is in the function "Insertar" because it expects a type char *variable but i an inserting just a char.
#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_
#include <stdio.h>
typedef struct
{
int dia;
int mes;
int ano;
}fecha;
struct NODEL
{
float valor;
char variable [10];
int resol;
fecha f;
struct NODEL* nextNode;
};
typedef struct NODEL LISTNODE;
typedef LISTNODE * LISTNODEPTR;
void insertar(LISTNODEPTR * lista, float newvalor, char *variable, int newresol,
#endif
void insertar(LISTNODEPTR * lista, float newvalor, char *variable, int newresol, int newdia, int newmes, int newano)
{
LISTNODEPTR newPtr, prevPtr, currPtr;
newPtr = malloc(sizeof(LISTNODE));
if(newPtr != NULL)
{
newPtr->valor = newvalor;
strncpy(newPtr->variable,newPtr->variable,10);
newPtr->resol = newresol;
newPtr->f.dia = newdia;
newPtr->f.mes = newmes;
newPtr->f.ano = newano;
newPtr->nextNode = NULL;
prevPtr = NULL;
currPtr = *lista;
while(currPtr != NULL && newvalor > currPtr->valor)
{
prevPtr = currPtr;
currPtr = currPtr->nextNode;
}
if(prevPtr == NULL)
{
newPtr->nextNode = *lista;
*lista = newPtr;
}
else
{
prevPtr->nextNode = newPtr;
newPtr->nextNode = currPtr;
}
}
else
{
printf("Elemento no insertado, no hay memoria disponible\n");
}
}
int main(void)
{
LISTNODEPTR data_base;
float valorADC;
char varIngresada;
int resolucion;
int diaIng;
int mesIng;
int anoIng;
printf("Valor de ADC: ");
scanf("%f", &valorADC);
fflush(stdin);
printf("Tipo variable 'Presion'/'Temperatura'/'Aceleracion': ");
scanf("%s", &varIngresada);
fflush(stdin);
printf("Resolución: ");
scanf("%d", &resolucion);
fflush(stdin);
printf("Fecha (dia): ");
scanf("%d", &diaIng);
fflush(stdin);
printf("Fecha (mes): ");
scanf("%d", &mesIng);
fflush(stdin);
printf("Fecha (año): ");
scanf("%d", &anoIng);
fflush(stdin);
insertar(&data_base, valorADC, varIngresada, resolucion, diaIng, mesIng, anoIng);
imprimir(data_base);
}

C List Segmentation Fault

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.

pointing wrong list member

it may be a nooby question, but can you explain me why running this i get printed the last member of the list instead of the first? am i missing something?
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
} ;
typedef struct nodo nodo;
nodo *leggi_lista(void);
int main (void) {
struct nodo *q;
q= NULL;
q=leggi_lista();
printf("%d\n\n", q->info); //should print first member of the list
return 0;
}
nodo *leggi_lista(void) { //creating list
nodo *p, *primo=NULL;
int i, n;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("Inserisci %d numeri: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->succ = primo;
primo = p;
}
return (primo) ;}
aaand i dunno what else i can add the post helper is bullying me :(
You are returning primo from the function which holds the value in p and this is got by the last malloc() and obviously you see the last value being printed out.
You need to fix your function to create the list. You need to keep your list's head intact and return the head from the function and print from head to end of list.

0xC0000005: Access violation reading location 0x00000008. C Code

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.

Resources