Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] Scrittura su File

    Buona sera a tutti,
    sono uno studente di ing. informatica al politecnico di Milano e stiamo praticamente terminando il corso sul C.

    Ho creato una rubrica funzionante dove posso aggiungere voci, stamparle a video, riordinarle ed effettuare una ricerca con una stringa che viene di volta in volta inserita dall'utente (e che dà come risultato tutte le "voci" della rubrica che contengono la nostra stringa "di ricerca").

    La mia domanda è se sia possibile scrivere tutta la rubrica su di un file e riuscire a leggerla comodamente. Mi spiego meglio. Ogni voce della rubrica è così composta:

    codice:
    typedef struct voce {
       	char nome[M];
        	char soprannome[M];
        	char cognome[M];
        	char numero[M];
     } voce;
    Se salvassi su di un file carattere per carattere (putc) o con una fpritf, otterei una serie di stringhe "scollegate". Vorrei sapere se esiste (su questo son certo) un metodo abbastanza veloce che permetta una lettura immediata alla riapertura del file/progetto/Pc.

    Infatti per andare a leggere tutte le voci della rubrica dovrei sapere dove sono e salvarle volta per volta in una stringa nuova (cambiando lunghezza del nome/cognome...... cambierebbe anche la posizione nel file).

    Grazie in anticipo per le vostre risposte, spero di essere stato abbastanza chiaro con la mia richiesta

  2. #2
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Ti conviene usare il classico fgets/fputs semplicemente xche hai un fine stringa. Per il tuo problema puoi usare fwrite e fread.
    Per gli Spartani e Sparta usa spartan Il mio github

  3. #3
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Ho incontrato lo stesso identico problema quando ho fatto la mia agenda elettronica,se tu vuoi scrivere i dati sul file in modo da poi poterli rileggere ordinatamente,una tecnica è di trattare il file riga per riga.
    Ho costruito una funzione apposita,che può leggere da qualsiasi file,questa funzione alloca dinamicamente la memoria necessaria a ospitare l' intera stringa.La stringa viene letta finchè non incontra il carattere newline,ed aggiunge il terminatore automaticamente,diviene a tutti gli effetti una stringa allocata sull' heap da liberare successivamente:
    codice:
    char *input (FILE *fp)
    {
        char *buffer;
        char checker;
        int size=1;
        buffer=(char*)malloc(sizeof(char));
        if(buffer==NULL)
        {
            printf("Errore di allocazione della memoria");
            exit(1);
        }
        while((buffer=getchar())!=10)
        {
            buffer[size-1]=checker;
            size++;
            buffer=(char*)realloc(buffer,size*sizeof(char));
            if(buffer==NULL)
            {
                printf("Errore di allocazione della memoria");
                exit(1);
            }
        }
        buffer[size-1]='\0';
        fflush(stdin);
    }
    Usando questa funzione leggo tutti i dati da file,scritti riga per riga.
    Poi quando vado a scrivere una stringa con fprintf aggiungo la newline:
    codice:
    fprintf(fp,"%s\n",stringa);
    E leggo tranquillamente come leggessi da stdin.
    Poi nella struttura per identificarle puoi aggiungere un intero che le identifica,ad esempio ogni struttura ha un serial number,a seconda del numero di righe che ha una struttura capisci quante righe dovrai leggere.
    Se tutte le strutture ad esempio hanno 7 righe,leggi 7 stringhe prima di passare a leggere la successiva.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    c'è un approccio assai più semplice.
    prima scrivi il numero di record, e poi i singoli campi.

    in fase di lettura leggi la prima riga (il numero record), e fai un banale ciclo che legge direttamente riga per riga.

    fine del problema.
    ----
    Ci sono poi approcci più "portabili", ossai file a lunghezza fissa, o CSV.
    Nel secondo caso inventati un delimitatore "strano" che ha poca probabilità
    di esserci tra i dati, (tipo !\$), giustapponilo ai singoli campi, uniscili e crea tante righe quanti record hai.

    Personalmente l'opzioni 1 è mooolto più semplice ed adatto per un progettino scolastico

  5. #5
    Perfetto l'idea riga per riga funziona, ora cercherò di applicarla ad un blocco di stringhe. Grazie mille per l'aiuto dato

  6. #6
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Prego
    Comunque ho sbagliato,al posto della getchar va inserito fgetc(fp),altrimenti legge solo da stdin.

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Io personalmente la scriverei in un file binario, usando fwrite e fread.
    In questo modo scrivi una serie di record tutti uguali che possono essere facilmente e velocemente riletti in un'array di record (o un singolo record, se è per questo) senza nessuna complicazione aggiuntiva.
    Tranne quella di non poter modificare il file con un editor di testo se ti dovesse servire.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  8. #8
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Un file .bin comunque lo puoi tranquillamente aprire col blocco note,non c'è differenza tra un file .txt e un file .bin,sono entrambe binari.

  9. #9
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    In linea teorica ok, ma nella pratica è diverso.

    Se scrivi sul file usando una funzione che formatta l'output, ad esempio fprintf, scrive in effetti del testo. Ad esempio, per scrivere il numero "1234567", occupa 7 caratteri. Se poi scrivi "25" ne occupa 2, etc.
    Se scrivi sul file usando fwrite, vengono scritti i dati in formato binario senza formattarli, perciò un intero, qualsiasi intero, occupa sempre 4 byte, ma è illeggibile in un editor di testo.

    Usando fwrite trascrivi sul file il blocco di memoria occupato dalla variabile, bit per bit, e non è detto (anzi, se non sono stringhe è quasi certo) che i byte che formano la variabile siano caratteri leggibili, figurati modificabili (pensa che se scrivi un double sul file, se provi a modificarlo quasi di sicuro lo "rompi" dato che il formato del double è un po' intricato).
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  10. #10
    Io ho praticamente risolto usando le fgets():

    codice:
                   FILE* p;
                   char buff[200];
                   char* pil;
    
                          pil=fgets(buff, 200, p);          /* Leggo una riga (200 serve tanto per tanto si ferma a \n)  */
                		
                	for(; !feof(p); num++)
                	{
                                		
                		buff[strlen(buff)-1] = '\0';                              /* siccome lo \n lo tiene dentro la stringa, allora lo tolgo */
                		if( p==NULL )	break;                                /* se il file non contiene nulla si ferma */
                		strcpy(&voce[num].nome, buff);, 200, p);      /* copio buff (senza a capo) nella stringa che mi serve */
            			
            			
            			fgets(buff, 200, p); 
                	}


    A questo punto nel ciclo for ci sono tante letture quanti voci della struct (nella mia altre 3). Così ogni ciclo prende n righe corrispondente a n campi, fino a quando non arriva alla fine del file. La lettura la faccio alla fine del for così il puntatore si sposta e riesce a riconoscere se il file è finito. Una buona sintesi delle risposte grazie ancora

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.