RISOLTO Esercizio con ricorsione con file e liste

Stato
Discussione chiusa ad ulteriori risposte.

sare1234

Utente Attivo
262
3
Buon pomeriggio sto provando a fare questo esercizio:
Un file contiene l’elenco degli ingredienti di una ricetta con i relativi pesi, nel seguente formato:
ingrediente unità di misura quantità
Le unità di misura possibili sono l (litri), g (grammi) e u (unità).
Il formato prevede l’inserimento di commenti nel file mediante il carattere ’#’ che deve precedere il testo del commento. Il commento termina alla fine della riga.
Si scriva un programma in C che letto unl file sorgente contenente i commenti, che ha estensione .tic, scriva un file con il medesimo nome ma estensione .toc contenente soltanto gli ingredienti e non i commenti.
#ingredienti per il ciambellone
latte l 0.25
farina g 300
olio l 0.05 # un cucchiaio
uova u 2
burro g 50
yogurt g 50 # yogurt bianco
# buon appetito
latte l 0.25
farina g 300
olio l 0.05
uova u 2
burro g 50
yogurt g 50

Allego la mia soluzione e spiego in seguito il problema:
Main.c
C:
#include <stdio.h>
#include <stdlib.h>
#include "funzioni.h"

int main(void){
    FILE * fp;
    struct Cibi * lista=NULL;
    fp=fopen("ingredienti.tic","r");
    if(fp!=NULL){
        printf("Leggo i dati dal file \"%s\"..\n","ingredienti.tic");
        lista=leggiFile(fp);
        fclose(fp);
        stampaLista(lista,stdout);
        fp = fopen("ingredienti.toc","w");
        scriviFile(fp,lista);
        fclose(fp);
    }
    return 0;
}

funzioni.h
C:
#ifndef funzioni_h
#define funzioni_h
#include <stdio.h>

#define MAXLEN 10

struct Cibi{
    char ingredienti[MAXLEN];
    char unitaDiMisura[1];
    float quantita;
    struct Cibi *next;
};

struct Cibi *leggiFile(FILE * input);
struct Cibi *inserisciCoda(struct Cibi * lista, struct Cibi * Cibi);
void stampaLista(struct Cibi * lista, FILE *stream);
void scriviLista(struct Cibi *lista);
void scriviFile(FILE *fp, struct Cibi *lista);
#endif

metodi.c
C:
#include "funzioni.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct Cibi * leggiFile(FILE * input){
    struct Cibi *tmp, *lista=NULL;
    while(!feof(input)){
        tmp=(struct Cibi*)malloc(sizeof(struct Cibi));
        fscanf(input,"%s\t %s\t %f\t ",tmp->ingredienti,tmp->unitaDiMisura,&tmp->quantita);
        lista=inserisciCoda(lista,tmp);
    }
    return lista;
}

struct Cibi * inserisciCoda(struct Cibi * lista, struct Cibi * Cibi){
    if(lista==NULL){
        Cibi->next=lista;
        return Cibi;
    }
    lista->next=inserisciCoda(lista->next,Cibi);
    return lista;
}

void stampaLista(struct Cibi * lista, FILE *stream){
    fprintf(stream,"\nStampa della lista:\n\n");
    while(lista!=NULL){
      fprintf(stream,"%s\t %s\t %2.2f\t\n",lista->ingredienti,lista->unitaDiMisura,lista->quantita);
        lista=lista->next;
    }
    fprintf(stream,"\nFine della stampa\n");
    return;
}



void scriviLista(struct Cibi *lista)
{
  while (lista!=NULL) {
    printf("%s\t %s\t %f\t\n",lista->ingredienti,lista->unitaDiMisura,lista->quantita);
      lista = lista->next;
  }
  printf("\n");
}

void scriviFile(FILE *fp, struct Cibi *lista)
{
  while (lista!=NULL) {
    fprintf(fp,"%s\t %s\t %f\t\n",lista->ingredienti,lista->unitaDiMisura,lista->quantita);
      lista = lista->next;
  }
}

Il problema che li stampa cosí:
1600263062509.png
Sapete aiutarmi a capire cosa sbaglio grazie in anticipo
 
U

Utente cancellato 371741

Ospite
Prima di tutto, i forum dovrebbero servire per chiedere piccole cose, non per farsi far egli esercizi, specie di scuola, farsi fare i compiti non serve a nulla, l'istruzione e' sempre piu scadente perche qualcuno cosi vuole, ormai si puo essere promossi senza capire nulla, e per cui imparare le cose veramente dipende solo da te.

Le righe di commento le devi scartare.

Io non avrei letto i campi con scanf, perche se uno usa spazi al posto dei tab facile che non funziona piu nulla. Avrei fatto delle classiche funzioni di trim per la lettura dei campi, tipo leggi la linea e fai qualcosa tipo

while ((*c == ' ') || (*c == '\t')) ++c;
 
Ultima modifica da un moderatore:
  • Mi piace
Reazioni: sare1234

sare1234

Utente Attivo
262
3
Prima di tutto, i forum dovrebbero servire per chiedere piccole cose, non per farsi far egli esercizi, specie di scuola, farsi fare i compiti non serve a nulla, l'istruzione e' sempre piu scadente perche qualcuno cosi vuole, ormai si puo essere promossi senza capire nulla, e per cui imparare le cose veramente dipende solo da te.

Le righe di commento le devi scartare.

Io non avrei letto i campi con scanf, perche se uno usa spazi al posto dei tab facile che non funziona piu nulla. Avrei fatto delle classiche funzioni di trim per la lettura dei campi, tipo leggi la linea e fai qualcosa tipo

while ((*c == ' ') || (*c == '\t')) ++c;
Grazie per la risposta ma se vorrei fare come ho fatto sopra cosa posso modificare?
 
U

Utente cancellato 371741

Ospite
Se vuoi usare sscanf, devi sapere esattamente cosa vuoi leggere.
1) Vuoli leggere "campo" o "il mio campo" ?
2) Hai sempre una regola fissa "nome nome numero"
sscanf puo fare un po di tutto, esempio, per "numero stringa numero"
Se hai spazi antecedenti la stringa invece di un tab, ci dev'essere modo sempre con sscanf, anche se ora non ricordo.

sscanf(string, "%d %[^0123456789]%d", &numero1, name, &numero2)

Secondo me, per un principiante, sscanf non aiuta a capire bene quel che si facendo.
 

sare1234

Utente Attivo
262
3
Se vuoi usare sscanf, devi sapere esattamente cosa vuoi leggere.
1) Vuoli leggere "campo" o "il mio campo" ?
2) Hai sempre una regola fissa "nome nome numero"
sscanf puo fare un po di tutto, esempio, per "numero stringa numero"
Se hai spazi antecedenti la stringa invece di un tab, ci dev'essere modo sempre con sscanf, anche se ora non ricordo.

sscanf(string, "%d %[^0123456789]%d", &numero1, name, &numero2)

Secondo me, per un principiante, sscanf non aiuta a capire bene quel che si facendo.
Vorrei leggere questo:
#ingredienti per il ciambellone
latte l 0.25
farina g 300
olio l 0.05 # un cucchiaio
uova u 2
burro g 50
yogurt g 50 # yogurt bianco
# buon appetito
Post unito automaticamente:

Vorrei leggere questo:
#ingredienti per il ciambellone
latte l 0.25
farina g 300
olio l 0.05 # un cucchiaio
uova u 2
burro g 50
yogurt g 50 # yogurt bianco
# buon appetito
C:
#include "funzioni.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Cibi * leggiFile(FILE * input){
    struct Cibi *tmp, *lista=NULL;
    while(!feof(input)){
        tmp=(struct Cibi*)malloc(sizeof(struct Cibi));
        fscanf(input,"%s %s %f\n",tmp->nome,tmp->unitaDiMisura,&tmp->quantita);
        lista=inserisciCoda(lista,tmp);
    }
    return lista;
}

struct Cibi * inserisciCoda(struct Cibi * lista, struct Cibi * Cibi){
    if(lista==NULL){
        Cibi->next=lista;
        return Cibi;
    }
    lista->next=inserisciCoda(lista->next,Cibi);
    return lista;
}

void stampaLista(struct Cibi * lista, FILE *stream){
    fprintf(stream,"\nStampa della lista:\n\n");
    while(lista!=NULL){
        fprintf(stream,"%6s\t %6s %10.2f\n",lista->nome,lista->unitaDiMisura,lista->quantita);
        lista=lista->next;
    }
    fprintf(stream,"\nFine della stampa\n");
    return;
}


void scriviLista(struct Cibi *lista)
{
  while (lista!=NULL) {
      printf("%6s %6s %10.2f\n",lista->nome,lista->unitaDiMisura,lista->quantita);
      lista = lista->next;
  }
  printf("\n");
}

void scriviFile(FILE *fp, struct Cibi *lista)
{
  while (lista!=NULL) {
      fprintf(fp,"%6s %6s %10.2f\n",lista->nome,lista->unitaDiMisura,lista->quantita);
      lista = lista->next;
  }
}

Ho provato cosi ma ho ancora il problema che i commenti non vengono stampati bene c'è cosi
1600328585414.png
 
Ultima modifica:
U

Utente cancellato 371741

Ospite
Bene, non ti ho risposto appositamente perche tu provi a svolgere l'esercizio.

Se vuoi insistere con quei maledetti scanf, io farei,

Codice:
leggi_riga
se commento
      scartare tutto da "#" in poi
sscanf sulla linea letta  (con formati corretti, "il ciambellone" contiene uno spazio)
 
  • Mi piace
Reazioni: sare1234

sare1234

Utente Attivo
262
3
Bene, non ti ho risposto appositamente perche tu provi a svolgere l'esercizio.

Se vuoi insistere con quei maledetti scanf, io farei,

Codice:
leggi_riga
se commento
      scartare tutto da "#" in poi
sscanf sulla linea letta  (con formati corretti, "il ciambellone" contiene uno spazio)
okay capito grazie
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili