RISOLTO Esercizio con ricorsione con file e liste

Pubblicità
Stato
Discussione chiusa ad ulteriori risposte.

sare1234

Utente Attivo
Messaggi
262
Reazioni
3
Punteggio
35
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.webp
Sapete aiutarmi a capire cosa sbaglio grazie in anticipo
 
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:
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?
 
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.
 
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
--- i due messaggi sono stati uniti ---
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.webp
 
Ultima modifica:
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)
 
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.
Pubblicità
Pubblicità
Indietro
Top