Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Problemino con i file
Forum - C/C++ - Problemino con i file

Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 21:21
Giovedì, 08/12/2011
Rieccomi con un altro "piccolo" problema.

Ho scritto questa funzione per leggere una struttura da file binario:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define CLIENTS_FILE "clients.dat"
  5.  
  6. // Struttura cliente
  7. typedef struct {
  8.     char name[50];
  9.     char surname[50];
  10.     float cost;
  11. } client;
  12.  
  13. int readClient()
  14. {
  15.     FILE *fp = NULL;
  16.     client c;
  17.     int i=0;
  18.    
  19.     if(!(fp=fopen(CLIENTS_FILE, "r")))
  20.     {
  21.         printf("Impossibile aprire il file \"%s\" in modalita' lettura.\n", CLIENTS_FILE);
  22.         return 0; // Se non riesce ad aprire il file ritorna 0
  23.     }
  24.    
  25.     while(fread(&c, sizeof(c), 1, fp)>0)
  26.     {
  27.         printf("\n--- CLIENTE #%d ---", i+1);
  28.         printf("Nome Cliente: %s\n", c.name);
  29.         printf("Cognome Cliente: %s\n", c.surname);
  30.         printf("Spesa: %f\n\n", c.cost);
  31.         i++;
  32.     }
  33.    
  34.     printf("\nTotale Clienti: %d\n", i);
  35.    
  36.     fclose(fp); // Chiudo il file
  37.    
  38.     return 1; // Se tutto va a buon fine ritorna 1
  39. }



Voi direte: dov'è il problema? Questa funzione è come se non entrasse proprio nel ciclo while perchè a video stampa solo "Totale Clienti: 0".
Premetto che:
1) Il file "clients.dat", ovviamente, non è vuoto ma con la funzione fwrite() scrivo una struttura client sul file stesso.
2) Il file "clients.dat" è nella stessa destinazione del file sorgente che contiene questa funzione.
3) Forse può essere banale come premessa però per evitare fraintesi ci tengo a precisare che, naturalmente, la funzione readClient() viene richiamata nella funzione main().

La cosa strana è che ho un altro file sorgente che ha il seguente codice:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define USER_FILE "user.dat"
  5.  
  6. // Struttura: Utente
  7. typedef struct {
  8.     char user[30];
  9.     char pass[30];
  10.     char email[50];
  11.     int age;
  12. } user;
  13.  
  14. int main()
  15. {
  16.     FILE *fp;
  17.     user u;
  18.     int size_w = 0; // Dimensione dei dati scritti su file
  19.     int i=0;
  20.    
  21.     if(!(fp=fopen(USER_FILE, "a")))
  22.     {
  23.         printf("Impossibile aprire il file \"%s\" in modalita' append.", USER_FILE);
  24.         exit(1);
  25.     }
  26.    
  27.     /* Inserimento nuovo utente */
  28.     printf ("===Inseririmento di un nuovo utente===\n\n");
  29.     printf ("Username: ");
  30.     scanf ("%s",u.user);
  31.     printf ("Password: ");
  32.     scanf ("%s",u.pass);
  33.     printf ("Email: ");
  34.     scanf ("%s",u.email);
  35.     printf ("Eta': ");
  36.     scanf ("%d",&u.age);
  37.    
  38.     if((size_w=fwrite(&u, sizeof(u), 1, fp))>0)
  39.     {
  40.         printf("Dati scritti con successo sul file!\n");
  41.         printf("Sono stati scritti %d B di dati.\n", size_w);
  42.     } else {
  43.         printf ("Errore nella scrittura dei dati su file\n");
  44.     }
  45.    
  46.     fclose(fp);
  47.    
  48.     if(!(fp=fopen(USER_FILE, "r")))
  49.     {
  50.         printf("Errore nell'apertura del file \"%s\" in modalita' lettura.", USER_FILE);
  51.         exit(1);
  52.     }
  53.    
  54.     while(fread(&u, sizeof(u), 1, fp)>0)
  55.     {
  56.         printf ("Username: %s\n",u.user);
  57.         printf ("Password: %s\n",u.pass);
  58.         printf ("Email: %s\n",u.email);
  59.         printf ("Eta': %d\n\n",u.age);
  60.         i++;
  61.     }
  62.    
  63.     printf ("Utenti letti nel file: %d\n",i);
  64.     fclose (fp);
  65.    
  66.     system("PAUSE");
  67.     return 0;
  68. }



Questo codice invece funziona. Sono un paio di giorni che mi sto scervellando per capire dov'è l'errore. Aiutatemi, per favore.

Ultima modifica effettuata da Driverfury il 08/12/2011 alle 21:24
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 21:38
Giovedì, 08/12/2011
Se devi accedere al file in binario allora devi utilizzare la modalità rb

if(!(fp=fopen(CLIENTS_FILE, "rb")))


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 22:03
Giovedì, 08/12/2011
Grazie, però sorge un altra domanda: perchè il secondo codice sorgente funziona anche se apro il file in modalità "r" anzichè "rb"?

Ultima modifica effettuata da Driverfury il 08/12/2011 alle 22:05
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 22:14
Giovedì, 08/12/2011
Perchè molto probabilmente il file è stato scritto in modo diverso (in modalità testo).

Per capire bene e avere tutte le spiegazioni, non basta avere solo il codice che legge ma bisogna avere

il codice che ha scritto
il file
il codice che legge


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 22:27
Giovedì, 08/12/2011
Ti assicuro che il file è stato scritto in modalità binaria (lo si capisce dalla costante del preproccessore USER_FILE che equivale a "user.dat"). Nella stessa cartella di "user.dat" c'era anche "user.txt" ma quando stampo a video i valori contenuti in "user.dat" escono quelli di "user.dat", quindi quelli del file binario. Pertanto il file è stato scritto in modalità binaria.

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 5475
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 22:36
Giovedì, 08/12/2011
Testo quotato

Postato originariamente da Driverfury:

Ti assicuro che il file è stato scritto in modalità binaria (lo si capisce dalla costante del preproccessore USER_FILE che equivale a "user.dat").



E cosa c'entra? Quella costante indica solo il nome del file non cosa ci sia dentro nè come è organizzato. L'estensione non ha nessuna importanza.

Testo quotato

Nella stessa cartella di "user.dat" c'era anche "user.txt" ma quando stampo a video i valori contenuti in "user.dat" escono quelli di "user.dat", quindi quelli del file binario. Pertanto il file è stato scritto in modalità binaria.



Ma che discorso è? Non c'entra nulla ...

Puoi anche scrivere in modalità testo e leggere in binario (se rispetti alcune regole, funziona) e anche viceversa ...

Ripeto ... per capirci qualcosa, bisogna *avere* (e controllare) i sorgenti che scrivono/leggono e il file in questione.

Ultima modifica effettuata da nessuno il 08/12/2011 alle 22:37


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
PM Quote
Avatar
Driverfury (Normal User)
Rookie


Messaggi: 45
Iscritto: 21/09/2011

Segnala al moderatore
Postato alle 11:07
Venerdì, 09/12/2011
Testo quotato

Postato originariamente da nessuno:

Ripeto ... per capirci qualcosa, bisogna *avere* (e controllare) i sorgenti che scrivono/leggono e il file in questione.



Capisco, ora che vuoi dire: se noti bene nel secondo file sorgente, nel main, c'è sia il codice che scrive su file con fwrite() che il codice che legge da file con fread(). Eppure nel secondo file sorgente il programma riesce a leggere da file anche se il file è aperto in modalità "r" e non "rb".

Nel secondo file sorgente, dunque, c'è il codice che SCRIVE, il codice che LEGGE e il file stesso.

P.S. Scusa per la risposta di prima, avevo frainteso quello che avevi scritto. ;)

Ultima modifica effettuata da Driverfury il 09/12/2011 alle 11:08
PM Quote