IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Lecture de fichier


Sujet :

C

  1. #1
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut Lecture de fichier
    Bonjour,

    J'ai un petit soucis de compréhension.
    Je dispose d'un fichier binaire structuré de la manière suivante.

    |un entier|une chaine 1|une chaine 2|une chaine 2|....|une chaine n|

    Chaque numéro de chaine possède un nombre x caractères connus. Le '|' n'est pas présent dans le fichier binaire, c'est juste pour marquer la séparation entre les types de données pour l'exemple ci dessus.

    Je voudrais pouvoir dans un premier temps récupérer l'entier. Un entier peut être composé de plusieurs caractères. Ce qui me pose problème est l'écriture du code permettant de lire le nombre de caractères qui compose l'entier pour ensuite reconstituer l'entier.

    Je ne vois pas comment m'en sortir avec les fonctions fseek, fread et fgets ou fgetc.

    Merci d'avance.

  2. #2
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    La fontion fseek est à proscrire en mode texte. Tu n'as pas besoin de connaitre le nombre de caractères de tes entiers, l'espace faisant office de séparateur à la fonction scanf qui accepte aussi bien des entiers que des flottants ou du texte, c'est juste ce qu'il te faut. Liste des séparateurs acceptés: isspace

    A+

    Pfeuh

  3. #3
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Ce n'est pas un fichier texte justement comme précisé mais bien un fichier binaire.

  4. #4
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Ooops, ça m'a paru tellement logique d'utiliser un fichier texte que je n'ai pas cherché plus loin. Alors le plus simple serait d'extraire tes octets représentant un nombre dans un buffer, de mettre un espace derrière et d'utiliser un sscanf. C'est comme un scanf, mais au lieu de lire dans un fichier on lit dans un buffer dont on passe l'adresse en paramètre. Il y a quand même quelque chose que je ne comprends pas, c'est si tes enregistrements sont répétitifs comme une structure ou si les tailles peuvent varier et sont stockées quelque part.

  5. #5
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    En fait l'entier donne le nombre d'enregistrement contenu dans le fichier binaire. Chaque enregistrement est un ensemble de 4 sous enregistrements dont on connait la taille. Donc pas de soucis de ce côté là.

    Je suis un peu à la rue sur ce coup ci. J'avoue que là y'a un gros truc qui m'échappe.

  6. #6
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    En fait je pense que j'ai trouvé. fread prend en paramètre un pointeur non typé. Je peux donc très bien choisir un entier ou un caractère. Il suffit que je me place à l'endroit voulu pour récupérer la donnée. Je vais donc me lancer dans le code et si j'ai un soucis je sais où vous trouver ^^

  7. #7
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    ça y 'est j'ai un soucis avec fread dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void CustomerDB_readRecord(CustomerDB *CustomerDB, int recordIndex, CustomerRecord *record)
    .

    Le compilateur m'insulte avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Gestion des clients\main.c||In function 'CustomerDB_readRecord':|
    Gestion des clients\main.c|192|error: expected expression before 'CustomerRecord'|
    Gestion des clients\main.c|192|error: too few arguments to function 'fread'|
    ||=== Build finished: 2 errors, 0 warnings ===|
    En fait dans le fichier binaire on trouve en premier un entier qui donne le nombre d'enregistrement et ensuite les enregistrement les uns à la suite des autres. Sachant que dans un enregistrement, on trouve 4 informations données par la structure CustomerRecord à savoir name, address, postalCode et town. Chacun ayant une taille max prédéfinie comme explicité juste ci dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #define CUSTOMERRECORD_NAME_SIZE 70
    #define CUSTOMERRECORD_ADDRESS_SIZE 130
    #define CUSTOMERRECORD_POSTAL_CODE_SIZE 20
    #define CUSTOMERRECORD_TOWN_SIZE 90
    #define CUSTOMERRECORD_SIZE ((long)( CUSTOMERRECORD_NAME_SIZE + \
                                         CUSTOMERRECORD_ADDRESS_SIZE + \
                                         CUSTOMERRECORD_POSTAL_CODE_SIZE + \
                                         CUSTOMERRECORD_TOWN_SIZE ) )
     
    typedef struct
    {
        char name[CUSTOMERRECORD_NAME_SIZE];
        char address[CUSTOMERRECORD_ADDRESS_SIZE];
        char postalCode[CUSTOMERRECORD_POSTAL_CODE_SIZE];
        char town[CUSTOMERRECORD_TOWN_SIZE];
    }CustomerRecord;
     
    typedef struct
    {
        FILE *file;
        int recordCount;
    }CustomerDB;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    void CustomerDB_readRecord(CustomerDB *CustomerDB, int recordIndex, CustomerRecord *record)
    {
        char CHAR_BUFFER[CUSTOMERRECORD_SIZE*recordIndex];
        char INT_BUFFER;
     
        /* On place le curseur après la valeur de recordCount */
        rewind(CustomerDB->file);
        size_t result = fread(&INT_BUFFER, sizeof(int), 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(int) );
     
        /* On place le curseur au début de l'enregistrement recherché */
        result = fread(CHAR_BUFFER, (recordIndex-1)*sizeof(char)*CUSTOMERRECORD_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, (recordIndex-1)*sizeof(char)*CUSTOMERRECORD_SIZE );
     
        /* On récupére le champs name de l'enregistrement et le curseur est situé au champ suivant de l'enregistrement courant */
        result = fread(CustomerRecord->name, sizeof(char)*CUSTOMERRECORD_NAME_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_NAME_SIZE );
     
        /* On récupére le champs address */
        result = fread(CustomerRecord->address, sizeof(char)*CUSTOMERRECORD_ADDRESS_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_ADDRESS_SIZE );
     
        /* On récupére le champs postalCode */
        result = fread(CustomerRecord->postalCode, sizeof(char)*CUSTOMERRECORD_POSTAL_CODE_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_POSTAL_CODE_SIZE );
     
        /* On récupére le champs town */
        result = fread(CustomerRecord->town, sizeof(char)*CUSTOMERRECORD_TOWN_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_TOWN_SIZE );
    }
    Et voici le code intégral si vous avez besoin de fouiller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    #include <stdio.h>
    #include <stdlib.h>
     
    #define CUSTOMERRECORD_NAME_SIZE 70
    #define CUSTOMERRECORD_ADDRESS_SIZE 130
    #define CUSTOMERRECORD_POSTAL_CODE_SIZE 20
    #define CUSTOMERRECORD_TOWN_SIZE 90
    #define CUSTOMERRECORD_SIZE ((long)( CUSTOMERRECORD_NAME_SIZE + \
                                         CUSTOMERRECORD_ADDRESS_SIZE + \
                                         CUSTOMERRECORD_POSTAL_CODE_SIZE + \
                                         CUSTOMERRECORD_TOWN_SIZE ) )
     
    typedef struct
    {
        char name[CUSTOMERRECORD_NAME_SIZE];
        char address[CUSTOMERRECORD_ADDRESS_SIZE];
        char postalCode[CUSTOMERRECORD_POSTAL_CODE_SIZE];
        char town[CUSTOMERRECORD_TOWN_SIZE];
    }CustomerRecord;
     
    typedef struct
    {
        FILE *file;
        int recordCount;
    }CustomerDB;
     
    void copyStringWithLength(char * dest, const char * src, size_t destSize)
    {
        destSize--;
        if ( dest != NULL && src != NULL )
        {
            size_t i;
            for ( i=0 ; i<destSize ; i++ )
            {
                dest[i] = src[i];
            }
     
            dest[destSize] = '\0';
        }
     
        else perror("An error has occured in the copyStringWithLength function ");
    }
     
    void CustomerRecord_setValue_name(CustomerRecord *record, const char *value )
    {
        copyStringWithLength( record->name, value, CUSTOMERRECORD_NAME_SIZE );
    }
     
    void CustomerRecord_setValue_address(CustomerRecord *record, const char *value )
    {
        copyStringWithLength( record->address, value, CUSTOMERRECORD_ADDRESS_SIZE );
    }
     
    void CustomerRecord_setValue_postal(CustomerRecord *record, const char *value )
    {
        copyStringWithLength( record->postalCode, value, CUSTOMERRECORD_POSTAL_CODE_SIZE );
    }
     
    void CustomerRecord_setValue_town(CustomerRecord *record, const char *value )
    {
        copyStringWithLength( record->town, value, CUSTOMERRECORD_TOWN_SIZE);
    }
     
    char *CustomerRecord_getValue_name(CustomerRecord *record)
    {
        return record->name;
    }
     
    char *CustomerRecord_getValue_address(CustomerRecord *record)
    {
        return record->address;
    }
     
    char *CustomerRecord_getValue_posta(CustomerRecord *record)
    {
        return record->postalCode;
    }
     
    char *CustomerRecord_getValue_town(CustomerRecord *record)
    {
        return record->town;
    }
     
    void CustomerRecord_init(CustomerRecord *record)
    {
        copyStringWithLength( record->name      , "", CUSTOMERRECORD_NAME_SIZE        );
        copyStringWithLength( record->address   , "", CUSTOMERRECORD_ADDRESS_SIZE     );
        copyStringWithLength( record->postalCode, "", CUSTOMERRECORD_POSTAL_CODE_SIZE );
        copyStringWithLength( record->town      , "", CUSTOMERRECORD_TOWN_SIZE        );
    }
     
    void CustomerRecord_finalize(CustomerRecord *record)
    {
        free(record->name);
        free(record->address);
        free(record->postalCode);
        free(record->town);
        free(record);
    }
     
    CustomerDB *CustomerDB_create(const char *filename)
    {
        CustomerDB *DB = (CustomerDB*)malloc(sizeof(CustomerDB));
     
        if ( DB == NULL )
        {
            exit(-1);
        }
     
        DB->file = fopen(filename, "wb+");
     
        if ( DB->file == NULL )
        {
            exit(-1);
        }
     
        return DB;
    }
     
    CustomerDB *CustomerDB_open(const char *filename)
    {
        CustomerDB *DB = (CustomerDB*)malloc(sizeof(CustomerDB));
     
        if ( DB == NULL )
        {
            exit(-1);
        }
     
        DB->file = fopen(filename, "rb+");
     
        if ( DB->file == NULL )
        {
            exit(-1);
        }
     
        return DB;
    }
     
    CustomerDB *CustomerDB_openOrCreate(const char *filename)
    {
        CustomerDB *DB = (CustomerDB*)malloc(sizeof(CustomerDB));
     
        if ( DB == NULL )
        {
            exit(-1);
        }
     
        DB->file = fopen(filename, "rwb+");
     
        if ( DB->file == NULL )
        {
            exit(-1);
        }
     
        return DB;
    }
     
    void CustomerDB_close(CustomerDB *DB)
    {
        fclose(DB->file);
    }
     
    void checkFreadReturn ( size_t result, size_t size )
    {
        if ( result != size ) { exit(-1); }
    }
     
    int getRecordCount(CustomerDB *CustomerDB)
    {
        rewind(CustomerDB->file);
        size_t result = fread(&CustomerDB->recordCount, sizeof(int), 1, CustomerDB->file);
        checkFreadReturn(result, sizeof(int));
     
        return CustomerDB->recordCount;
    }
     
    void CustomerDB_readRecord(CustomerDB *CustomerDB, int recordIndex, CustomerRecord *record)
    {
        char CHAR_BUFFER[CUSTOMERRECORD_SIZE*recordIndex];
        char INT_BUFFER;
     
        /* On place le curseur après la valeur de recordCount */
        rewind(CustomerDB->file);
        size_t result = fread(&INT_BUFFER, sizeof(int), 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(int) );
     
        /* On se place le curseur au début de l'enregistrement recherché */
        result = fread(CHAR_BUFFER, (recordIndex-1)*sizeof(char)*CUSTOMERRECORD_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, (recordIndex-1)*sizeof(char)*CUSTOMERRECORD_SIZE );
     
        /* On récupére le champs name de l'enregistrement */
        result = fread(CustomerRecord->name, sizeof(char)*CUSTOMERRECORD_NAME_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_NAME_SIZE );
     
        /* On récupére le champs name */
        result = fread(CustomerRecord->address, sizeof(char)*CUSTOMERRECORD_ADDRESS_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_ADDRESS_SIZE );
     
        /* On récupére le champs name */
        result = fread(CustomerRecord->postalCode, sizeof(char)*CUSTOMERRECORD_POSTAL_CODE_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_POSTAL_CODE_SIZE );
     
        /* On récupére le champs name */
        result = fread(CustomerRecord->town, sizeof(char)*CUSTOMERRECORD_TOWN_SIZE, 1, CustomerDB->file);
        checkFreadReturn( result, sizeof(char)*CUSTOMERRECORD_TOWN_SIZE );
    }
     
     
    int main()
    {
     
        return 0;
    }

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void CustomerDB_readRecord(CustomerDB *CustomerDB, int recordIndex, CustomerRecord *record)
    {
    .....
        /* On récupére le champs name de l'enregistrement et le curseur est situé au champ suivant de l'enregistrement courant */
        result = fread(CustomerRecord->name, sizeof(char)*CUSTOMERRECORD_NAME_SIZE, 1, CustomerDB->file);
    .....
    CustomerRecord est un type, pas un objet. Probablement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        result = fread(record->name, sizeof(char)*CUSTOMERRECORD_NAME_SIZE, 1, CustomerDB->file);
    idem pour les fread() qui suivent.

  9. #9
    Membre éclairé
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2007
    Messages
    731
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : amateur

    Informations forums :
    Inscription : Octobre 2007
    Messages : 731
    Par défaut
    Eh beh oui aie aie aie ! Merci bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Windows]lecture des fichier lnk (raccourcis)
    Par Tiaps dans le forum API standards et tierces
    Réponses: 10
    Dernier message: 21/10/2009, 19h27
  2. [jsp]lecture de fichier
    Par antigone dans le forum Servlets/JSP
    Réponses: 9
    Dernier message: 04/09/2003, 11h05
  3. [AS400][Intranet][PC] Lecture de "fichiers" AS400
    Par lando dans le forum Autres SGBD
    Réponses: 4
    Dernier message: 16/07/2003, 11h11
  4. Lecture de fichier
    Par Watcha dans le forum x86 16-bits
    Réponses: 13
    Dernier message: 04/03/2003, 20h43
  5. Lecture de fichiers ".WAV"...
    Par 0x4e84 dans le forum Langage
    Réponses: 2
    Dernier message: 03/09/2002, 09h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo