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++Builder Discussion :

Fichier binaire et structure


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 132
    Par défaut Fichier binaire et structure
    Bonjour,

    J'essaie de construire un fichier binaire avec une structure. C'est un essai.

    Lors de l'ouverture, j'ai comme message d'erreur : "Abnormal program termination"

    Curieusement, si je retire la ligne ListBox2->Items->Add(personnes.nom + " " + personnes.ville+ " " +IntToStr(personnes.num) );
    Pas de message d'erreur.

    J'aimerais utiliser mon fichier de façon classique :
    - Enregistrer
    - Modifier (avec Fseek ?)
    - Supprimer (avec Fseek ?)

    Je cherche des solutions sur le net, pas moyen ... et je rame

    Ci-dessous mon code.

    Si vous avez une solution, merci d'avance.

    Cordialement

    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
     
    struct PERSONNE
     {
      String nom;
      String ville;
      int num;
     };
     PERSONNE personnes;
     int pos;
     
    void __fastcall TForm2::EnregistrerStructClick(TObject *Sender)
    {
       // Ecriture
     
      int i;
     
      ofstream fichier ("Repertoire.xyz", ios::out | ios :: app);
     
     
      if(!fichier.is_open())
     
    	 {
    	  ShowMessage ("Impossible de créer le fichier");
    	  return;
    	 }
     
      else
    	{
    	  personnes.nom = Edit2->Text;
    	  personnes.ville = Edit3->Text;
    	  personnes.num = pos;
    	  pos+=1;
    	  fichier.write ((char *)&personnes, sizeof(PERSONNE));
    	}
     
    	fichier.close();
    }
     
    void __fastcall TForm2::OuvertureStructClick(TObject *Sender)
    {
     ListBox2->Clear();
      int i;
     
     ifstream fichier ("Repertoire.xyz", ios::in );
     
     
     if (!fichier.is_open())
     
    	 {
    	  ShowMessage ("Impossible d'ouvrir le fichier");
    	  return;
    	 }
      else
     
       {  while (!fichier.eof())
    	 {
    	  fichier.read ((char *)&personnes, sizeof(PERSONNE));
    	  ListBox2->Items->Add(personnes.nom + " " + personnes.ville+ " " +IntToStr(personnes.num) );
    	 }
       }
     
      fichier.close();
     
     }

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 600
    Par défaut
    Bonjour,

    On ne peut pas faire fichier.write ((char *)&personnes, sizeof(PERSONNE)); et encore moins fichier.read ((char *)&personnes, sizeof(PERSONNE));. Le fait d'avoir utilisé le cast du C au lieu du cast C++ empêche le compilateur de prévenir de l'énormité.
    Ces fonctions attendent des suites d'octets en paramètres, mais ta struct PERSONNE n'est pas ce que l'on appelle un "POD", en prendre la taille ne correspond pas du tout à ce qu'il y a à l'intérieur. Les données internes sont des pointeurs dans la mémoire et copier ces pointeurs ne correspond à rien. Les relire est encore plus grave, c'est pourquoi immédiatement après cette lecture le code ne peut que planter lamentablement.
    Pour écrire la structure, on peut utiliser une structure au format C, là ça marchera.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct PERSONNE {  // Ça c'est un "POD" mais ça n'est plus vraiment du C++
      char nom[20];
      char ville[20];
      int num;
     };
    Ou bien il faut un moyen de sérialiser et désérialiser ta structure

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 132
    Par défaut
    Bonjour Dalfab.

    Merci. J'ai essayé avec char mais il y a toujours une erreur au niveau de ListBox2->Items->Add(personnes.nom + " " + personnes.ville+ " " +IntToStr(personnes.num) );

    [bcc32 Erreur] Fich.cpp(209): E2085 Addition de pointeur incorrecte
    Contexte d'analyseur complet
    Fich.cpp(193): analyse : void _fastcall TForm2::OuvertureStructClick(TObject *)
    [bcc32 Erreur] Fich.cpp(254): E2277 Lvalue nécessaire

    J'ai converti char en String(personnes.nom), toujours la même erreur.

    Le code ci-dessous ne marche pas mieux, toujours une erreur à cause de la ligne ListBox2->Items->Add(personnes.nom + " " + personnes.ville + " " +IntToStr(personnes.num));
    Si je la supprime, pas d'erreur.

    Cordialement

    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
     
    struct PERSONNE
     {
      String nom;
      String ville;
      int num;
     };
     PERSONNE personnes;
     int pos;
     
    void __fastcall TForm2::EnregistrerStructClick(TObject *Sender)
    {
       // Ecriture
    FILE * fichier;
    	fichier = fopen ("Repertoire.xyz", "ab");
     
      if (fichier == NULL) ShowMessage("Impossible d'ouvrir le fichier");
     
    	 else
    	 {
    	  personnes.nom = Edit2->Text;
    	  personnes.ville = Edit3->Text;
    	  personnes.num = pos;
    	  pos+=1;
    	  fwrite (&personnes,sizeof(PERSONNE),1,fichier);
    	  ListBox1->Items->Add(personnes.nom + " " + personnes.ville+ " " +IntToStr(personnes.num) );
    	 }
     
       fclose(fichier);
     
     }
     
    void __fastcall TForm2::OuvertureStructClick(TObject *Sender)
    {
     ListBox2->Clear();
     
     FILE * fichier;
     fichier = fopen ("Repertoire.xyz", "rb");
     
      if (fichier == NULL) ShowMessage("Impossible d'ouvrir le fichier");
     
      else
     {
       while (! feof(fichier))
    	{
    		{
    		fread(&personnes,sizeof(PERSONNE),1,fichier);
    		ListBox2->Items->Add(personnes.nom + " " + personnes.ville + " " +IntToStr(personnes.num));
    		}
    	}
     
     }
    	fclose (fichier);
     
     }

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 600
    Par défaut
    Citation Envoyé par magdani Voir le message
    Si je la supprime, pas d'erreur.
    Quelle erreur? une erreur à l'exécution (est-ce "Abnormal program termination"?) ou une erreur de compilation?

    On ne peut pas additionner des char*, mais on peut concaténer un String avec un char*, il faut convertir au moins un élément sur deux en String:
    ListBox2->Items->Add( String(personnes.nom) + " " + String(personnes.ville) + " " + IntToStr(personnes.num) );

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 132
    Par défaut
    Merci dalfab.

    Plus de plantage : personnes.num s'affiche bien dans listbox

    Par contre, toujours un problème avec les chaînes de caractères.

    personnes.nom = Edit2->Text; [bcc32 Erreur] Fich.cpp(253): E2277 Lvalue nécessaire
    Normal, incompatibilité entre char et string.

    J'ai essayé de convertir string en char

    strcpy(personnes.nom,Edit2->Text.c_str()); [bcc32 Erreur] Fich.cpp(252): E2342 Mauvaise correspondance de type dans le paramètre '__src' ('const char *' désiré, 'wchar_t *' obtenu)

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 600
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 600
    Par défaut
    Si à un moment on a besoin de wchar_t, il est préférable de ne pas utiliser les char mais des wchar_t à la place.
    - les strcpy() deviennent alors des wcscpy(),
    - les "...." deviennent des L"....."
    - ... ça devient compliqué. ...

    On peut passer par les AnsiString qui devraient permettre de convertir les String en char* et inversement.

    On bien on peut se poser la question ne ne pas utiliser un tableau au format C, d'oublier les char et wchar_t, apprendre le langage C est peut-être de trop! On peut revenir à sérialiser les écritures des String. Il doit y avoir des outils sous C++ Builder pour faciliter cela.

Discussions similaires

  1. Lecture fichier binaire avec structure connue
    Par sdecorme dans le forum Scilab
    Réponses: 1
    Dernier message: 08/12/2016, 13h25
  2. Lecture/écriture fichier binaire via structure
    Par Tenebrous dans le forum C
    Réponses: 9
    Dernier message: 07/03/2010, 00h02
  3. Réponses: 9
    Dernier message: 04/06/2007, 21h44
  4. Réponses: 5
    Dernier message: 26/03/2007, 01h30

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