Item extraction from a list in C - 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;
}

Related

Segmentation fault error in Linked-List program

I'm facing the segmentation fault error in the following dynamic linked list implementation; GDB shows the issue is on the node = node->next line in the "l_print" function of the linked-list ("LIST_CL.H" file). Anyone can help? I even tried "drawing debug" on paper but still I'm not getting the issue here.
Note: I report the whole code for both the insert and the print, in case it's useful. Therefore LIST.C file include the "switch case 6" to insert the element ("l_add" function in "LIST_CL.H" file) and the "switch case 1" to print the list ("l_print" function in "LIST_CL.H" file)
Note: The issue only happen when the list has one or more items. There's no errors when the list is empty ("list_cl" struct has NULL for both head and tail nodes)
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Select command:");
puts("0. Exit.");
puts("1. Insert node.");
puts("6. Print all nodes in the linked list.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
char first_name[STRING_SIZE] = "";
char last_name[STRING_SIZE] = "";
getchar();
puts("Insert name:");
fgets(first_name, sizeof(first_name), stdin);
puts("Insert surname:");
fgets(last_name, sizeof(last_name), stdin);
puts("Insert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client cliente;
strcpy(cliente.cf, cf);
cliente.first_name = first_name;
cliente.last_name = last_name;
class = l_add_cl(class, cliente);
puts("Node inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
scanf("%d", &k);
}
}
LIST_CL.H:
list_cl l_add_cl(list_cl l, client p){
l_node node;
node.id = 1;
node.person = p;
node.next = NULL;
if(l.head == NULL){
//List is empty
l.head = &node;
l.tail = &node;
} else {
l.tail -> next = &node;
l.tail = &node;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
//client *cliente = &node->person;
//printf("ID Elemento: %d | Name: %s Surname: %s Fiscal Code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next; // SEGMENTATION FAULT ERROR HERE!
}
}
CL_LIST.H:
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H:
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;
Fixed code:
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Seleziona un comando:");
puts("0. Exit.");
puts("1. Insert one node.");
puts("6. Print all nodes.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
//char first_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
//char last_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
char *first_name = malloc(sizeof(char)*STRING_SIZE);
char *last_name = malloc(sizeof(char)*STRING_SIZE);
getchar();
puts("Insert name:");
//fgets(first_name, sizeof(first_name), stdin); ISSUE WITH SIZE OF FIRST_NAME
fgets(first_name, sizeof(char)*STRING_SIZE, stdin);
puts("Insert surname:");
//fgets(last_name, sizeof(last_name), stdin); ISSUE WITH SIZE OF LAST_NAME
fgets(last_name, sizeof(char)*STRING_SIZE, stdin);
puts("IInsert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client *cliente = malloc(sizeof(client));
strcpy(cliente->cf, cf);
cliente->first_name = first_name;
cliente->last_name = last_name;
class = l_add_cl(class, *cliente);
puts("Element inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
puts("Select command:");
scanf("%d", &k);
}
}
LIST_CL.H
list_cl l_add_cl(list_cl l, client p){
l_node *node = malloc(sizeof(struct _node));
node->id = 1;
node->person = p;
node->next = NULL;
if(l.head == NULL){
//Empty list
l.head = node;
l.tail = node;
} else {
l.tail -> next = node;
l.tail = node;
l.tail -> next = NULL;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
client *cliente = &node->person;
printf("ID Element: %d | Name: %s Surname: %s Fiscal code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next;
}
}
CL_LIST.H
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;

Static List with open hashing C

Im a begginer developer and i need help!
I have a txt file of 2287 lines
Contains ID (int), Name (string), Number1, Number2, Number3 (all 3 floats).
"
1234 Jose 10 11 12
...
...
"
I need to get the data from this file and implement a Hash table in separate chain WITH static list.
Also needs to have Insert, Remove and Search functions.
I have so many problems until now.
I dont know how to put it with a static list, and before that i cant hash it properly, its all NULLs..
Anyone can help?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define max 2287
int main(){
FILE* fp;
fp = fopen("dados.txt","r");
if (fp==NULL){
printf("Erro na abertura\n");
system("pause");
exit(1);
}
struct aluno{
int matricula;
char nome[30];
float n1,n2,n3;
struct aluno *next;
};
struct aluno aluno[max];
struct aluno *hash[max];
//povoando com os dados
int i=0;
for(i=0;i<max;i++){
fscanf(fp,"%d %s %f %f %f\n", &aluno[i].matricula, &aluno[i].nome, &aluno[i].n1, &aluno[i].n2, &aluno[i].n3);
}
//teste pra ver se o fscanf funcionava
printf("%s %d %f" , aluno[3].nome, aluno[2].matricula, aluno[1].n1);
void inicializa()
{
int i;
for(i = 0; i < max; i++)
hash[i] = NULL;
}
void insere(int valor){
//cria a newAluno com o valor
struct aluno *newAluno = malloc(sizeof(struct aluno));
newAluno->matricula = valor;
newAluno->next = NULL;
//calcula a chave hash
int chave = valor % max;
//checa se esta null
if(hash[chave] == NULL)
hash[chave] = newAluno;
else{
struct aluno *temp = hash[chave];
while(temp->next){
temp = temp->next;
}
temp->next = newAluno;
}
}
int busca(int valor){
int chave = valor % max;
struct aluno *temp = hash[chave];
while(temp){
if(temp->matricula == valor)
return 1;
temp = temp->next;
}
return 0;
}
void print(){
for(i = 0; i < max; i++)
{
struct aluno *temp = hash[i];
printf("hash[%d]-->",i);
while(temp)
{
printf("%d -->",temp->matricula);
temp = temp->next;
}
printf("NULL\n");
}
}
print();
return 0;
}

c How to insert a element in a sublist

I have a list of products of several categories in the file "Magazzino.txt" here below:
A451XX (codice prodotto)
CAT001 (codice categoria)
PASTA CONF. 1KG
100
99.0
A451XY (codice prodotto)
CAT002 (codice categoria)
MAGLIA LANA
25
6.70
A452XX (codice prodotto)
CAT001 (codice categoria)
SUGO
33
9.99
First I have to read the file and copy all products in a list with the following structure:
typedef struct {
char codP[C];
char codC[C];
char descr[D];
int num;
float costo;
} tipoBaseLista;
typedef struct nodoLista{
tipoBaseLista info;
struct nodoLista *next;
}prodotto;
typedef prodotto *listaP;
I need to copy this list of products in a list of categories such that each category has a sublist with all product that belong to the specific category. The structure of this list of list is:
typedef struct nodoCat{
char codC[C];
struct nodoCat *next;
listaP nodoP; //puntatore al sottonodo prodotto
}categoria;
typedef categoria *listaC;
This is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define C 8
#define D 64
typedef struct {
char codP[C];
char codC[C];
char descr[D];
int num;
float costo;
} tipoBaseLista;
typedef struct nodoLista{
tipoBaseLista info;
struct nodoLista *next;
}prodotto;
typedef prodotto *listaP;
typedef struct nodoCat{
char codC[C];
struct nodoCat *next;
listaP nodoP;
}categoria;
typedef categoria *listaC;
int carica_lista(char fName[], listaP *l);
void inserimentoProd(listaP *l, tipoBaseLista p);
listaC trovaCategoria(listaC lc, char categoria[]);
void inserimentoSottolista(listaC lc, tipoBaseLista p, listaP *l);
int main() {
char filename[] = "Magazzino.txt";
listaP lista = NULL;
listaC listaCat = NULL;
tipoBaseLista prodotto;
printf("\nNumero prodotti caricati: %d\n", carica_lista(filename, &lista));
if(lista == NULL){
printf("\nLa lista dei prodotti è vuota!\n");
}
while(lista != NULL){
prodotto = lista->info;
if(listaCat == NULL){
listaCat = malloc(sizeof(categoria));
strcpy(listaCat->codC, prodotto.codC);
listaCat->next = NULL;
inserimentoSottolista(listaCat, prodotto, &lista);
}
else{
listaCat = trovaCategoria(listaCat, prodotto.codC);
if(listaCat != NULL){
inserimentoSottolista(listaCat, prodotto, &lista);
}
else{
listaCat = listaCat->next;
inserimentoSottolista(listaCat, prodotto, &lista);
}
}
lista = lista->next;
}
return 0;
system("PAUSE");
}
//read from file
int carica_lista(char fName[], listaP *l) {
tipoBaseLista prodotto;
int n = 0;
char buf[D] = {0};
char scarto[30];
FILE *f;
f = fopen(fName, "r");
if (f == NULL) {
printf("Non e' possibile aprire il file\n");
exit(1);
}
while (!feof(f)) {
fgets(buf, sizeof(buf), f);
sscanf(buf, "%s%s", prodotto.codP, scarto);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%s%s", prodotto.codC, scarto);
fgets(buf, sizeof(buf), f);
strcpy(prodotto.descr, buf);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%d", &prodotto.num);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%f", &prodotto.costo);
inserimentoProd(l, prodotto);
n++;
}
fclose(f);
return n;
system("PAUSE");
}
//to insert product in the list
void inserimentoProd(listaP *l, tipoBaseLista p){
listaP pCorrente = NULL;
listaP pNodo;
listaP pPrec;
pNodo = malloc(sizeof(prodotto));
pNodo->info = p;
pNodo->next = NULL;
if (*l == NULL){
*l = pNodo;
}
else if(strcmp(p.codP, (*l)->info.codP) < 0){
pNodo->next = *l;
*l = pNodo;
(*l)->next = pNodo;
}
else{
pCorrente = *l;
while (pCorrente->next != NULL && strcmp(p.codP, pCorrente->info.codP) > 0){
pPrec = pCorrente;
pCorrente = pCorrente->next;
}
if(strcmp(p.codP, pCorrente->info.codP) < 0){
pNodo->next = pCorrente;
pPrec->next = pNodo;
}
else if(pCorrente->next == NULL) {
pCorrente->next = pNodo;
}
}
}
//To find the category node under which we insert the sublist
listaC trovaCategoria(listaC lc, char categoria[]){
listaC pCorrente = lc;
while(pCorrente != NULL){
if(strcmp(pCorrente->codC, categoria) == 0){
printf("\nCategoria già presente.\n");
return pCorrente;
}
pCorrente = pCorrente->next;
}
return(NULL);
}
//to insert the product in the head of sublist
void inserimentoSottolista(listaC lc, tipoBaseLista p, listaP *l){
printf("\nInserimento nella sottolista\n");
listaP prodotto = malloc(sizeof(struct nodoLista));
prodotto->info = p;
prodotto->next = *l;
*l = prodotto;
lc->nodoP = prodotto;
printf("\nInserimento effettuato\n");
}
There must be some problem in the "inserimentoSottolista" that cause the crash of the program. What could it be?
The problem is here, inside inserimentoSottolista:
listaP prodotto = malloc(sizeof(prodotto));
You need sizeof(prodotto) to be the size of the struct that was declared earlier, i.e. sizeof(struct nodoLista). But you have used the same name for the name of the variable being initialized. In this case, the prodotto in sizeof(prodotto) isn't the struct, but is the variable. So sizeof(prodotto) ends up being the same as sizeof(listaP), which is just the size of a pointer. It's too small, so you aren't allocating enough memory.
You can fix it by changing the variable name so that it doesn't mask the type name, or by using sizeof(struct nodoLista).

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

Save structs in a file

I'm doing a program to save a list of contacts in a file whit structs. I've tried a lot of things but when I try go read the file to the program, it doesn't read anything.
This is my program without opening files and saving to files:
#include <stdio.h>
#include <stdlib.h>
struct agenda {
int idContacte;
char name[50];
struct agenda *nextContacte;
};
struct agenda *pAgenda;
struct agenda *pFirst = NULL;
struct agenda *pIndex;
void insert();
void show();
int main()
{
//Menu
int opc;
while(1){
printf("1.Insert Contact.\n");
printf("2.Show Contacts.\n");
printf("3.Exit\n");
scanf("%d", &opc);
switch(opc){
case 1:
insert();
break;
case 2:
show();
break;
case 3:
return 0;
}
}
}
void insert(){
pAgenda = (struct agenda *)malloc(sizeof(struct agenda));
printf("Insert ID: ");
scanf("%d", &pAgenda->idContacte);
printf("Insert the name: ");
scanf("%s", pAgenda->name);
printf("\n");
if (pFirst==NULL || pAgenda->idContacte < pFirst->idContacte)
{
pAgenda->nextContacte=pFirst;
pFirst=pAgenda;
}
else if (pAgenda->idContacte > pFirst->idContacte){
pIndex=pFirst;
while(pIndex->nextContacte && pIndex->nextContacte->idContacte < pAgenda->idContacte)
{
pIndex = pIndex->nextContacte;
}
pAgenda->nextContacte = pIndex->nextContacte;
pIndex->nextContacte = pAgenda;
}
}
void show(){
pIndex = pFirst;
while(pIndex && pIndex->idContacte <= 100) {
printf("\nID: %d", pIndex->idContacte);
printf("\nNAME: %s", pIndex->name);
printf("\n\n");
pIndex = pIndex->nextContacte;
}
}
Can you help me how can I get contact at start of the program from a file, and then when insert a contact, rewrite the file and insert all the contacts again in the file?
When you end your program you should do the following
int save_list(struct agenda *head) {
FILE *save = fopen("file.name", "wb");
if(!save) return -1;
while(head) {
fwrite(head, sizeof *head - sizeof head, 1, save);
head = head->nextContacte;
}
fclose(save);
/* Somebody would free list memory after this function execution */
return 0;
}
At the start of your program you should do the following
struct agenda *restore_list() {
FILE *restore= fopen("file.name", "rb");
struct agenda *head = NULL;
struct agenda *cur = head;
struct agenda temp;
if(!restore) return head;
while( fwrite(&temp, sizeof temp - sizeof head, 1, save) == 1) {
struct agenda *node = malloc( sizeof(struct agenda) );
if(NULL == node) {
/* Handle out of memory error here, free list */
return NULL;
}
*node = temp;
node->nextContacte = NULL;
if(head) {
cur->nextContacte = node;
cur = node;
} else {
/* First node */
head = cur = node;
}
}
fclose(restore);
return head;
}

Resources