Oppure

Loading
08/12/11 20:21
Driverfury
Rieccomi con un altro "piccolo" problema.

Ho scritto questa funzione per leggere una struttura da file binario:
#include <stdio.h>
#include <stdlib.h>

#define CLIENTS_FILE "clients.dat"

// Struttura cliente
typedef struct {
    char name[50];
    char surname[50];
    float cost;
} client;

int readClient()
{
    FILE *fp = NULL;
    client c;
    int i=0;
    
    if(!(fp=fopen(CLIENTS_FILE, "r")))
    {
        printf("Impossibile aprire il file \"%s\" in modalita' lettura.\n", CLIENTS_FILE);
        return 0; // Se non riesce ad aprire il file ritorna 0
    }
    
    while(fread(&c, sizeof(c), 1, fp)>0)
    {
        printf("\n--- CLIENTE #%d ---", i+1);
        printf("Nome Cliente: %s\n", c.name);
        printf("Cognome Cliente: %s\n", c.surname);
        printf("Spesa: %f\n\n", c.cost);
        i++;
    }
    
    printf("\nTotale Clienti: %d\n", i);
    
    fclose(fp); // Chiudo il file
    
    return 1; // Se tutto va a buon fine ritorna 1
}


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:
#include <stdio.h>
#include <stdlib.h>

#define USER_FILE "user.dat"

// Struttura: Utente
typedef struct {
    char user[30];
    char pass[30];
    char email[50];
    int age;
} user;

int main()
{
    FILE *fp;
    user u;
    int size_w = 0; // Dimensione dei dati scritti su file
    int i=0;
    
    if(!(fp=fopen(USER_FILE, "a")))
    {
        printf("Impossibile aprire il file \"%s\" in modalita' append.", USER_FILE);
        exit(1);
    }
    
    /* Inserimento nuovo utente */
    printf ("===Inseririmento di un nuovo utente===\n\n");
    printf ("Username: ");
    scanf ("%s",u.user);
    printf ("Password: ");
    scanf ("%s",u.pass);
    printf ("Email: ");
    scanf ("%s",u.email);
    printf ("Eta': ");
    scanf ("%d",&u.age);
    
    if((size_w=fwrite(&u, sizeof(u), 1, fp))>0)
    {
        printf("Dati scritti con successo sul file!\n");
        printf("Sono stati scritti %d B di dati.\n", size_w);
    } else {
        printf ("Errore nella scrittura dei dati su file\n");
    }
    
    fclose(fp);
    
    if(!(fp=fopen(USER_FILE, "r")))
    {
        printf("Errore nell'apertura del file \"%s\" in modalita' lettura.", USER_FILE);
        exit(1);
    }
    
    while(fread(&u, sizeof(u), 1, fp)>0)
    {
        printf ("Username: %s\n",u.user);
        printf ("Password: %s\n",u.pass);
        printf ("Email: %s\n",u.email);
        printf ("Eta': %d\n\n",u.age);
        i++;
    }
    
    printf ("Utenti letti nel file: %d\n",i);
    fclose (fp);
    
    system("PAUSE");
    return 0;
}


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 08/12/11 20:24
aaa
08/12/11 20:38
Se devi accedere al file in binario allora devi utilizzare la modalità rb

if(!(fp=fopen(CLIENTS_FILE, "rb";)))
08/12/11 21:03
Driverfury
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 08/12/11 21:05
aaa
08/12/11 21:14
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
08/12/11 21:27
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";). 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.
aaa
08/12/11 21:36
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.

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 08/12/11 21:37
09/12/11 10:07
Driverfury
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 09/12/11 10:08
aaa