c How to insert a element in a sublist - c

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).

Related

Idk how to get info from a .dat file and make a single linked list from that using C

This is my code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LENG 100
#define PAGE_LENG 30
typedef struct pDB {
char model[MAX_LENG];
char ram[MAX_LENG];
char memSpace[MAX_LENG];
char screenSize[MAX_LENG];
char price[MAX_LENG];
}phonedb;
struct nod {
phonedb phone;
struct nod* next;
};
typedef struct nod node;
node* root, * prev, * cur;
node *newNode(phonedb p)
{
node* new = malloc(sizeof(node));
new->phone = p;
new->next = NULL;
return new;
}
void insertAfterCur(phonedb p)
{
FILE* fptr;
fptr = fopen("phonedb.dat", "rb");
while (fread(&p, sizeof(phonedb), 1, fptr))
{
if (root == NULL)
{
root = newNode(p);
cur = root;
}
else
{
cur->next = newNode(p);
cur = cur->next;
}
}
fclose(fptr);
}
int main()
{
phonedb p;
int inp;
FILE* fptr;
FILE* fptr2;
while (1)
{
printf("2. Create a list from dat\n");
printf("3. Print all database\n");
printf("4. Quit\n");
scanf("%d", &inp);
switch (inp)
{
case(2):
insertAfterCur(p);
break;
case(3):
for (cur = root; cur != NULL; cur = cur->next)
{
printf("%s %s %s %s %s\n", cur->phone.model, cur->phone.ram, cur->phone.memSpace, cur->phone.screenSize, cur->phone.price);
}
break;
case(4):
exit(1);
}
}
}
it only printed out 1 line of infor and the rest are '\n' with the price infor a printed as some strange characters. My phonedb struct has model, ram, memspace, screensize and price which are all strings and node struct contains a phonedb type and a pointer.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LENG 100
#define PAGE_LENG 30
typedef struct pDB {
char model[MAX_LENG];
char ram[MAX_LENG];
char memSpace[MAX_LENG];
char screenSize[MAX_LENG];
int price;
}phonedb;
void importDBtext(FILE* fptr, FILE* fptr2);
int lineCount(FILE* fptr);
int main()
{
phonedb p;
int inp;
FILE* fptr;
FILE* fptr2;
while (1)
{
printf("1. Convert txt to dat\n");
printf("5. Quit\n");
scanf("%d", &inp);
switch (inp)
{
case(1):
fptr = fopen("phonedb.txt", "r");
fptr2 = fopen("phonedb.dat", "wb+");
importDBtext(fptr, fptr2);
fclose(fptr);
fclose(fptr2);
break;
case(5):
exit(1);
}
}
}
int lineCount(FILE* fptr)
{
char* c;
c = malloc(6969 * sizeof(char*));
int count = 0;
while (fgets(c, 6969, fptr))
count++;
rewind(fptr);
return count;
}
void importDBtext(FILE* fptr, FILE* fptr2)
{
phonedb *p;
p = malloc(lineCount(fptr) * sizeof(phonedb));
int i = 0;
while (fscanf(fptr, "%s %s %s %s %d", p[i].model, p[i].ram, p[i].memSpace, p[i].screenSize, &p[i].price) != EOF)
{
i++;
}
fwrite(p, sizeof(phonedb), i, fptr2);
}

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

Filling Gtk Tree Store from a file

I'm trying to fill a gtk tree store from a linked list but i get the segmentation fault (core dumped) problem here is my code File to struct is a linked list filled a struct to a professor and a next the professor is defined by a name matiere password pseudo...etc
store = gtk_list_store_new (NUM_COLUMNNS,G_TYPE_INT,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_INT);
File_to_struct *p=head;
/* add data to the list store */
while(p!=NULL)
{
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMNN_ID,p->professeur.ID,
COLUMNN_NOM,p->professeur.nom,
COLUMNN_MATIERE,p->professeur.matiere,
COLUMNN_PSEUD,p->professeur.pseudo,
COLUMNN_PASS,p->professeur.password,
COLUMNN_VALIDE,p->professeur.valide,
-1);
p=p->suivant;
}
FILE fichier=fopen("professeur.txt","r");
Prof professeur;
File_to_struct *tete=(File_to_struct)malloc(sizeof(File_to_struct));
tete=NULL;
rewind(fichier);
while((!feof(fichier)))
{
fscanf(fichier,"\n%s %s %s %s %d %d\n",professeur.nom,professeur.matiere,professeur.pseudo,professeur.password, &pro‌​fesseur.valide,&professeur.ID);
tete=inserer(tete,professeur); }
typedef struct prof{
int ID;
int valide;
char nom[40];
char matiere[40];
char password[40];
char pseudo[40]; }Prof;
typedef struct file_to_struct{
Prof professeur;
struct file_to_struct *suivant; }File_to_struct;
You have problems when filling the list, this is an example of how to do it correctly
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Prof
{
int ID;
int valide;
char nom[40];
char matiere[40];
char password[40];
char pseudo[40];
} Prof;
typedef struct File_to_struct
{
Prof professeur;
struct File_to_struct *suivant;
} File_to_struct;
File_to_struct *
inserer(File_to_struct *Debut, Prof profs)
{
File_to_struct *nv;
File_to_struct *actuel;
nv = malloc(sizeof(File_to_struct));
if (nv == NULL)
return Debut;
nv->suivant = NULL;
nv->professeur = profs;
actuel = Debut;
if (Debut == NULL)
Debut = nv;
else
{
while (actuel->suivant != NULL)
actuel = actuel->suivant;
actuel->suivant = nv;
}
return Debut;
}
char **
splitString(const char *const text, const char *const delimiter, int *count)
{
char *copy;
char *pointer;
char *token;
char *saveptr;
char **list;
if ((text == NULL) || (count == NULL) || (delimiter == NULL))
return NULL;
copy = strdup(text);
*count = 0;
pointer = copy;
list = NULL;
while ((token = strtok_r(pointer, delimiter, &saveptr)) != NULL)
{
void *auxiliary;
auxiliary = realloc(list, (1 + *count) * sizeof(char *));
if (auxiliary == NULL)
{
while (*count >= 0)
{
free(list[*count]);
*count -= 1;
}
free(copy);
free(list);
return NULL;
}
list = auxiliary;
list[*count] = strdup(token);
*count += 1;
pointer = NULL;
}
free(copy);
return list;
}
Prof
extractProfesseur(const char *const line)
{
char **list;
int count;
Prof prof;
memset(&prof, 0, sizeof(prof));
list = splitString(line, " ", &count);
if (count < 6)
{
while (--count >= 0)
free(list[count]);
free(list);
return prof;
}
prof.ID = strtol(list[4], NULL, 10);
prof.valide = strtol(list[5], NULL, 10);
strncpy(prof.nom, list[0], 39);
strncpy(prof.matiere, list[1], 39);
strncpy(prof.pseudo, list[2], 39);
strncpy(prof.password, list[3], 39);
while (--count >= 0)
free(list[count]);
free(list);
return prof;
}
int
main()
{
FILE *fichier;
File_to_struct *tete;
File_to_struct *actuel;
char line[256];
fichier = fopen("professeur.txt","r");
if (fichier == NULL)
return -1; /* n'pouvez pas de ouvrir le fichier */
tete = NULL;
rewind(fichier);
while (fgets(line, sizeof(line), fichier) != NULL)
{
Prof professeur;
professeur = extractProfesseur(line);
tete = inserer(tete, professeur);
}
actuel = tete;
while (actuel != NULL)
{
Prof prof;
File_to_struct *previous;
prof = actuel->professeur;
previous = actuel;
actuel = actuel->suivant;
printf("%s %s %s %s %d %d\n", prof.nom, prof.matiere,
prof.pseudo, prof.password, prof.valide, prof.ID);
free(previous);
}
fclose(fichier);
return 0;
}

Linked list only grabbing last input of File contents

I'm trying to upload a list from a outside FILE into a linked list and have all the chars from the FILE be accessible on the list. I have this so far, but It only contains the last word from my input file list. I don't know what the problem is and I'm not sure where to go from here. Any help would be great! Thank you.
My .txt file that I'm uploading is just a bunch of nonsense words like:
Ted
Greg
Shoe
Money
Apple
When I run the program the list would only contain the would Apple.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 15
#define INPUT 1
#define OUTPUT 2
struct tree_node{
char string[MAXLEN+1];
struct tree_node *left_child, *right_child;
}*first = NULL;
int main(int argc, char *argv[])
{
char cell[MAXLEN];
int op;
FILE *pf;
FILE *out;
pf = fopen(("%s", argv[INPUT]), "r");
if(pf == NULL){
fprintf(stderr, "Error: File is Empty. \n");
return 0;
}else{
struct tree_node *temp;
struct tree_node *nn=(struct tree_node*)malloc(sizeof(struct tree_node));
while(!feof(pf)){
// fgets(&nn->string, MAXLEN, pf);
fscanf(pf, "%s", &nn->string); //I think this is where the problem is.
if(first != NULL){
temp = first;
while(temp -> right_child != NULL)
temp = temp -> right_child;
temp -> right_child = nn;
}else{
first = nn;
}
nn->right_child = NULL;
}
}
do{
printf("1.Display.\n2.Exit.\n");
printf("Selection?\n");
scanf("%d", &op);
switch(op)
{
case 1:display();
break;
}
}
while(op < 2 && op > 0);
}
int display()
{
struct tree_node *temp;
temp = first;
if(temp == NULL)
{
printf("EMPTY!\n");
return;
}
printf("Elements: \n");
while(temp != NULL){
printf("%s\n", temp -> string);
temp = temp -> right_child;
}
}
fscanf(pf, "%s", &nn->string); Here string is char array. so remove&.
You created only one node. This section above while().
struct tree_node *temp;
struct tree_node *nn=(struct tree_node*)malloc(sizeof(struct tree_node));
Need to create separate node for each string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 15
#define INPUT 1
#define OUTPUT 2
#define EXIT 2
#define _S(x) #x
#define S(x) _S(x)
struct tree_node{
char string[MAXLEN+1];
struct tree_node *left_child, *right_child;
}*first = NULL;
void display(void);
void add_tree(char string[MAXLEN+1]);
int main(int argc, char *argv[]){
char cell[MAXLEN+1];
int op;
FILE *pf, *out;
if(NULL==(pf = fopen(argv[INPUT], "r"))){
fprintf(stderr, "Error: File can't open.\n");
return 1;
}
while(fscanf(pf, " %" S(MAXLEN) "[^\n]", cell)==1){
add_tree(cell);
}
fclose(pf);
do{
printf("1.Display.\n2.Exit.\n");
printf("Selection?\n");
scanf("%d", &op);
switch(op){
case 1:
display();
break;
}
} while(op != EXIT);
//release tree
return 0;
}
struct tree_node* new_node(char string[MAXLEN+1]){
struct tree_node *np = malloc(sizeof(*np));
if(np){
strcpy(np->string, string);
np->left_child = np->right_child = NULL;
}
return np;
}
void insert(struct tree_node **np, char string[MAXLEN+1]){
int cmp;
if(*np == NULL){
*np = new_node(string);
return;
}
if(0==(cmp=strcmp((*np)->string, string)))
return;
if(cmp > 0)
insert(&(*np)->left_child, string);
else
insert(&(*np)->right_child, string);
}
void add_tree(char string[MAXLEN+1]){
insert(&first, string);
}
void display_r(struct tree_node *np){
if(np){
display_r(np->left_child);
printf("%s\n", np->string);
display_r(np->right_child);
}
}
void display(void){
if(first == NULL){
printf("EMPTY!\n");
return;
}
printf("Elements: \n");
display_r(first);
}

Creating a list from ".bin" file in C

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
}

Resources