Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Esercizio sui file...
Forum - C/C++ - Esercizio sui file...

Avatar
xshell32 (Normal User)
Rookie


Messaggi: 34
Iscritto: 08/02/2008

Segnala al moderatore
Postato alle 23:44
Martedì, 29/12/2009
Ciao. Stavo creando di svolgere qualche esercizio per migliorare le mie conoscenze sul linguaggio... ma in questo caso non riesco a capire bene che cosa sia richiesto. Non voglio assolutamente lo svolgimento, solo capire cosa richieda il testo.

TESTO: Il file binario dati.bin contiene una sequenza di numeri reali lunga N. Scrivere un programma C completo che legga da tastiera il numero N e legga poi dal file tale sequenza memorizzandola in un vettore.

Se ho capito bene ho un file binario contenente una serie di numeri (separati da uno spazio immagino) e io devo creare una funzione per capire quanti numeri sono presenti... giusto? Ma dice anche "che legga da tastiera il numero N"... che significa?


#include<stdio.h>
#include<stdlib.h>

main()
{
   FILE *fp;
   if((fp = fopen("dati.bin", "rb"))==NULL)
        exit(1);

   fread();

   fclose(fp);
}

Ultima modifica effettuata da xshell32 il 30/12/2009 alle 0:48
PM Quote
Avatar
Matthew (Member)
Expert


Messaggi: 387
Iscritto: 29/01/2007

Segnala al moderatore
Postato alle 2:29
Mercoledì, 30/12/2009
Significa che l'utente avvia il programma e gli viene chiesto di digitare il numero di numeri (scusate il gioco di parole) presenti nel file. Questo numero (N) viene poi usato per leggere il file e memorizzare i dati in un array di dimensione N. Chiaro?

PM Quote
Avatar
Lawliet (Normal User)
Expert


Messaggi: 386
Iscritto: 09/04/2009

Segnala al moderatore
Postato alle 2:57
Mercoledì, 30/12/2009
Ma prima di leggere hai provato a scrivere?
E già sei volato alla lettura "binaria"?
Comunque chiede semplicemente di inserire a run time(non ne sono sicuro se si può dire così, potrei sbagliarmi) il numero degli elementi che devi leggere e poi inserire nel vettore.
N non è proprio la dimensione dell'array come scritto da matthew, c'è differenza e la traccia non lo dice esplicitamente ma fa nulla ^^' :).


Ultima modifica effettuata da Lawliet il 30/12/2009 alle 2:58
PM Quote
Avatar
xshell32 (Normal User)
Rookie


Messaggi: 34
Iscritto: 08/02/2008

Segnala al moderatore
Postato alle 11:06
Mercoledì, 30/12/2009
Grazie. Ma se N non è la dimensione del vettore (che deve sempre essere una costante, quindi una variabile darebbe errore), che cos'è precisamente?

Con uno scanf() inserisco il numero 10, ad esempio, e tale numero lo dovrei inserire in fread() per leggere 10 numeri reali... (vettore, sizeof(float), N, fp)... però il vettore...? Una malloc()?

PM Quote
Avatar
xshell32 (Normal User)
Rookie


Messaggi: 34
Iscritto: 08/02/2008

Segnala al moderatore
Postato alle 12:14
Mercoledì, 30/12/2009
Questa è una prova... non è proprio come dice il testo, però mi serve per capire come funzionano le cose... e infatti non funzionano! :rofl:

Domandina: scrivendo "w+b" oppure "wb+" (che dovrebbero essere la stessa cosa), non apro il file sia in scrittura che in lettura? Perché il programma funziona se dopo aver scritto il file binario, io lo chiudo e lo riapro con "rb"... Oppure converebbe aprirlo con "a+" e con fseek() riportare il "puntatore" all'inizio del file?

Codice sorgente - presumibilmente C/C++

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. main()
  5. {
  6.    FILE *fp;
  7.    int num, N,i;
  8.    int arra[30];
  9.    int array[]={4,2,6,1,2,67,4,5,43,2,9};
  10.    fp = fopen("dati.bin", "w+b");
  11.    fwrite(array, sizeof(int),8,fp);
  12.    
  13.    printf("Inserire un numero: ");
  14.    scanf("%d", &N);
  15.    
  16.    fread(arra, sizeof(int),N, fp);
  17.    
  18.    printf("Gli elementi del vettore sono: ");
  19.    for(i=0; i<N; i++)
  20.    {
  21.        printf("%d ", arra[i]);  
  22.    }
  23.    fclose(fp);
  24.    system("pause");
  25.    return 0;
  26. }



Ecco una seconda prova... più completa... ma non funzionante... deve esserci ancora qualche problemuccio. Cosa ne dite?

Codice sorgente - presumibilmente C/C++

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. main()
  5. {
  6.    FILE *fp;
  7.    int numeroinit, numerofin, i;
  8.    float *arrayinit, *arrayfin;
  9.  
  10.    printf("Numero di elementi del vettore: ");
  11.    scanf("%d", &numeroinit);
  12.    
  13.    arrayinit=malloc(sizeof(float)*numeroinit);
  14.    
  15.    if(arrayinit==NULL)
  16.    {
  17.         printf("Memoria esaurita!");
  18.         printf("\n\n");
  19.         system("pause");
  20.         exit(1);
  21.    }
  22.    
  23.    printf("Inserire %d numeri decimali: ", numeroinit);
  24.    
  25.    for(i=0; i<numeroinit; i++)
  26.    {
  27.         scanf("%f", &arrayinit[i]);
  28.    }
  29.    
  30.    if((fp=fopen("dati.bin", "ab+"))==NULL)
  31.    {
  32.         printf("Errore!");
  33.         printf("\n\n");
  34.         system("pause");
  35.         exit(1);  
  36.    }
  37.    
  38.    fwrite(arrayinit, sizeof(float), numeroinit, fp);
  39.    rewind(fp);
  40.    
  41.    printf("Quanti numeri vuoi leggere dal file? ");
  42.    scanf("%d", &numerofin);
  43.    
  44.    arrayfin=malloc(sizeof(float)*numerofin);
  45.    
  46.    fread(arrayfin,sizeof(float),numerofin,fp);
  47.  
  48.    
  49.    printf("I numeri presenti nel file sono: ");
  50.    
  51.    for(i=0; i<numerofin; i++)
  52.    {
  53.        printf("%f ", arrayfin[i]);  
  54.    }
  55.    
  56.    fclose(fp);
  57.    
  58.    system("pause");
  59.    return 0;
  60. }




Ultima modifica effettuata da xshell32 il 30/12/2009 alle 14:39
PM Quote
Avatar
Lawliet (Normal User)
Expert


Messaggi: 386
Iscritto: 09/04/2009

Segnala al moderatore
Postato alle 0:58
Giovedì, 31/12/2009
Allora, vedo che hai idee confuse..e non di poco!! (Ci sarà un motivo?!)
Ricordo e ribadisco, che saltare e andare avanti è solo DELETERIO!.
Provo a rispondere alle tue domande:

Testo quotato

Postato originariamente da xshell32:
Ma se N non è la dimensione del vettore (che deve sempre essere una costante, quindi una variabile darebbe errore),


Non ho capito nulla di ciò che hai scritto. Rispondo a quella di sotto:
Testo quotato


che cos'è precisamente?


A capire dalla traccia, è la dimensione del vettore da leggere in modalità binaria. Visto che non lo sai quanto deve essere un unico modo per farlo è utilizzare la malloc. (sai a cosa serve e come si usa!?)


Testo quotato

Postato originariamente da xshell32:
Questa è una prova... non è proprio come dice il testo, però mi serve per capire come funzionano le cose... e infatti non funzionano! :rofl:

Prima si studia e poi si passa all'opera ^^'

Testo quotato

Postato originariamente da xshell32:
Domandina: scrivendo "w+b" oppure "wb+" (che dovrebbero essere la stessa cosa), non apro il file sia in scrittura che in lettura? Perché il programma funziona se dopo aver scritto il file binario, io lo chiudo e lo riapro con "rb"... Oppure converebbe aprirlo con "a+" e con fseek() riportare il "puntatore" all'inizio del file?

Aha.. queste "domandine" le dovresti capire dal libro se le stai studiando ^^'
fseek() non serve per riportare, anzi.. c'è la funzione rewind() che serve a quello che hai detto tu.

Cosa ti chiede la traccia? Leggere quindi, basta un rb.. ma per farlo devi aver già scritto quindi.. potresti prima fare un "wb" e poi riapri leggendo in modalità binaria "rb" oppure fare entrambi senza dover aprire e chiudere: "w+b" o "wb+" indifferente che sono uguali.

Nel primo programmino che hai fatto sembra che non sono presenti errori, ma ovviamente se immetti un numero superiore a 8 è ovvio che si mostrearanno numeri casuali e non di quelli del vettore ^^'.

Nel secondo programmino..

Codice sorgente - presumibilmente Plain Text

  1. fwrite(arrayinit, sizeof(float), numeroinit, fp);


è sbagliato.

Codice sorgente - presumibilmente Plain Text

  1. fwrite(arrayinit, sizeof(arrayinit), numeroinit, fp);



Così ci scrivi tutta la struttura array vettore, oppure potevi fare come prima cioè inserire elemento per elemento però.
La stessa cosa vale ovviamente anche per la fread.

Presta più attenzione al libro ed eviteresti sti errori ;)
Spero di non aver tralasciato nulla.. alla prossima ^^

Ultima modifica effettuata da Lawliet il 31/12/2009 alle 1:25
PM Quote
Avatar
xshell32 (Normal User)
Rookie


Messaggi: 34
Iscritto: 08/02/2008

Segnala al moderatore
Postato alle 18:59
Sabato, 02/01/2010
Testo quotato

Postato originariamente da Lawliet:

Testo quotato

Postato originariamente da xshell32:

Ma se N non è la dimensione del vettore (che deve sempre essere una costante, quindi una variabile darebbe errore).



Non ho capito nulla di ciò che hai scritto.



Scusami, ma la sintassi base del C e del C++ penso di conoscerla abbastanza bene (apparte qualche dubbio sull'uso di alcune particolari funzioni della Standard Library). Intendevo dire che il vettore deve avere una dimensione (il numero di elementi) costante, quindi non posso inserire N come dimensione del vettore, perché quest'ultima è una variabile... quindi uso la funzione malloc().

Testo quotato

Postato originariamente da Lawliet:
A capire dalla traccia, è la dimensione del vettore da leggere in modalità binaria. Visto che non lo sai quanto deve essere un unico modo per farlo è utilizzare la malloc. (sai a cosa serve e come si usa!?)


Sì, sò usare la malloc(). Serve per allocare dinamicamente la memoria, e in questo caso è utile per creare un vettore di dimensioni arbitrarie.

Codice sorgente - presumibilmente C/C++

  1. int N;
  2. float *array;
  3. scanf("%f", &N);
  4. array = (float *)malloc(sizeof(float)*N);




Testo quotato

Postato originariamente da Lawliet:
Aha.. queste "domandine" le dovresti capire dal libro se le stai studiando ^^'
fseek() non serve per riportare, anzi.. c'è la funzione rewind() che serve a quello che hai detto tu.


Mi spiace contraddirti, ma rewind() svolge la stessa funzione di fseek(stream, 0L, SEEK_SET); quindi usare un rewind() o un fseek() con la costante SEEK_SET è identico... solo che con rewind scrivi di meno... :rofl:

Testo quotato

Postato originariamente da Lawliet:
Cosa ti chiede la traccia? Leggere quindi, basta un rb.. ma per farlo devi aver già scritto quindi.. potresti prima fare un "wb" e poi riapri leggendo in modalità binaria "rb" oppure fare entrambi senza dover aprire e chiudere: "w+b" o "wb+" indifferente che sono uguali.



Sì, basta un "rb", ma se volessi scrivere e leggere un file con lo stesso programma dovrei necessariamente aprire e chiudere il file due volte con modalità diverse? Ho provato con "wb+", ma il file non viene letto... forse con "a+"?

Testo quotato

Postato originariamente da Lawliet:
Nel primo programmino che hai fatto sembra che non sono presenti errori, ma ovviamente se immetti un numero superiore a 8 è ovvio che si mostrearanno numeri casuali e non di quelli del vettore ^^'.


Era un programmino di esempio... ho inserito manualmente i valori in un vettore per valutare solo la scrittura e la lettura del file. Il problema del vettore con la malloc l'avrei affrontato in seguito...

Testo quotato

Postato originariamente da Lawliet:
Nel secondo programmino..

Codice sorgente - presumibilmente Plain Text

  1. fwrite(arrayinit, sizeof(float), numeroinit, fp);


è sbagliato.

Codice sorgente - presumibilmente Plain Text

  1. fwrite(arrayinit, sizeof(arrayinit), numeroinit, fp);



Così ci scrivi tutta la struttura array vettore, oppure potevi fare come prima cioè inserire elemento per elemento però.
La stessa cosa vale ovviamente anche per la fread.


Grazie. Hai ragione: devo inserire la dimensione di tutto l'array, non solo quella del singolo elemento. :k:

Testo quotato

Postato originariamente da Lawliet:
Presta più attenzione al libro ed eviteresti sti errori ;)
Spero di non aver tralasciato nulla.. alla prossima ^^


Sicuramente. :D Però posso assicurarti che ho studiato vari libri, ma secondo me per imparare alla perfezione un linguaggio è necessaria molta pratica, perché con i soli libri si potrebbero commettere sempre errori logici o errori su qualche argomento non ben chiarito sulla carta... ad esempio, nel libro è scritto che "wb+" serve per aprire un file in modalità "scrittura + lettura binaria", ma quando ho eseguito il codice la funzione fread() non funzionava correttamente... questi errori li puoi scoprire solo scrivendo e compilando molto codice (quello che sto cercando di fare).

Grazie per il supporto! Ciao e auguri di buon anno (anche se un po' in ritardo). :D

Ultima modifica effettuata da xshell32 il 02/01/2010 alle 19:17
PM Quote
Avatar
Lawliet (Normal User)
Expert


Messaggi: 386
Iscritto: 09/04/2009

Segnala al moderatore
Postato alle 20:29
Sabato, 02/01/2010
Testo quotato

Postato originariamente da xshell32:
Scusami, ma la sintassi base del C e del C++ penso di conoscerla abbastanza bene (apparte qualche dubbio sull'uso di alcune particolari funzioni della Standard Library). Intendevo dire che il vettore deve avere una dimensione (il numero di elementi) costante, quindi non posso inserire N come dimensione del vettore, perché quest'ultima è una variabile... quindi uso la funzione malloc().


No problem... potresti pure farlo benissimo.. non vedo il problema :)

Testo quotato

Postato originariamente da xshell32:
Mi spiace contraddirti, ma rewind() svolge la stessa funzione di fseek(stream, 0L, SEEK_SET); quindi usare un rewind() o un fseek() con la costante SEEK_SET è identico... solo che con rewind scrivi di meno... :rofl:


mmm... io non l'ho mai usato.. non mi serve xD, ho usato altre funzioni per quel genere problema ^^'

Testo quotato

Postato originariamente da xshell32:
Sì, basta un "rb", ma se volessi scrivere e leggere un file con lo stesso programma dovrei necessariamente aprire e chiudere il file due volte con modalità diverse? Ho provato con "wb+", ma il file non viene letto... forse con "a+"?

"
Si dovresti aprire e chiudere due volte per accedere alle due modalità, ma con "wb+" sbagli secondo me, forse "rb+" è più adatto.. così non devi necessariamente ricreare il file, ma solo leggere sempre se esiste e poi successivamente scrivere o leggere.. oppure se non esiste allora usi la modalità "wb+" e non legge appunto perchè hai creato un nuovo file. Capito? Non so se mi sono spiegato bene.
Anche "a+" potrebbe andare:
"Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist."
Però non parte dall'inizio ma in coda e non crea file..
Dipende da cosa vuoi fare.

PM Quote