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 :

programme affiche code bizarre après avoir enregistré un fichier texte dans un tableau de struct


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Biélorussie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Mars 2017
    Messages : 3
    Par défaut programme affiche code bizarre après avoir enregistré un fichier texte dans un tableau de struct
    Bonjour à tous,

    Je veux faire un code simple qui enregistre le contenu d'un fichier texte dans un tableau de structure. Ce fichier a une quinzaine de lignes, chacune sous la forme Nom, Prenom, (tabulation), caractère pour le poste, suivis de deux flottants. (Par exemple : Tremblay Alain A 35.0 35.5). Lorsque j’affiche le tableau on dirait que tout se passe bien, seulement le programme affiche plein de caractères entre le dernier nom et le « Au revoir! » de fin, comme ça :

    1.35632e-019 1.75442e-019
    o 1.84946e+031 3.03345e+032 … sur une dizaine de ligne environ.

    Voici le code:

    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
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
     
     
     
    struct Employe {          // Structure employé
        string nom;
        char poste;
        float heures, salHor;
    };
     
    int compter (int n){
        string lignes;
        ifstream fichier1 ("Employes.dat");
     
        while (getline(fichier1, lignes))
        n++;
     
        fichier1.close();
        return n;
    }
     
    int main () {
     
        int nbEmp=0;
        nbEmp=compter(nbEmp);
     
        Employe *ptrTabEmploye; //Creer nouveau tableau
        ptrTabEmploye = new Employe [nbEmp];
     
        ifstream fichier ("Employes.dat");  //Ouverture du fichier
     
        if (fichier)
        {  
        for (int i =0; i<nbEmp; i++)   //Met les données dans le tableau
         {
            getline(fichier, ptrTabEmploye[i].nom, '\t');
            fichier >> &ptrTabEmploye[i].poste;
            fichier >> ptrTabEmploye[i].heures;
            fichier >> ptrTabEmploye[i].salHor;
          } 
        } else {
            cout << "ERREUR D'OUVERTURE" << endl;
        }
     
        for (int i=0; i<nbEmp; i++)
        {
            cout  << ptrTabEmploye[i].nom <<" "  <<ptrTabEmploye[i].poste <<" " <<ptrTabEmploye[i].heures
          <<" " << ptrTabEmploye[i].salHor <<  "\n"<<endl; //Test
          }
     
         delete [] ptrTabEmploye;
     
        cout << "\nAu revoir!"<<endl;
     
     
     
          return 0; 
    }
    J’ai essayé sans allocation dynamique de mémoire (sans new[]) mais le drôle de code est encore là mais change de forme, ça devient surtout des zéros… J’ai regardé sur plusieurs forum en français et en anglais mais je ne trouve pas de problème similaire, si vous voyez ce qui bloque ou connaissez un sujet de forum semblable je prendrais volontier l'info ou le lien

    Merci encore et bonne journée!

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Que se passe-t-il si tu as des lignes vides à la fin de ton fichier ?
    Si tu arrives à reproduire ce phénomène avec un fichier sans ligne vide à la fin, merci de nous l'envoyer pour qu'on puisse tester.

    Sinon, une remarque : Lire deux fois le fichier simplement pour connaître la taille au début, je trouve ça vraiment pas terrible. Il vaudrait mieux que tu utilises un vector<Employe> pour stocker tes employés, et faire des push_back pour ajouter les employés dedans au fur et à mesure. Et le reste de ton code en sera lui aussi simplifié (plus besoin de delete[]).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2017
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Biélorussie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Alimentation

    Informations forums :
    Inscription : Mars 2017
    Messages : 3
    Par défaut
    Rebonjour,

    J'ai vérifié, il n'y avait pas de lignes vides à la fin du fichier, mais j'en ai rajouté pour voir ce que ça faisait. Il imprime alors la quantité de ligne vide ajouté entre le dernier nom et les chiffres bizarre, mais ceux ci sont toujours là. J'ai regardé aussi s'il y avait des espaces à la fin des lignes et j'ai remarqué qu'il y avait un espace après chaque dernier flottant donc je les ai supprimés, mais il affiche exactement la meme chose. J'ai essayé après d'enlever la tabulation entre les nom et caracteres du poste mais pareil...

    Voici le fichier complet:
    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
    Tremblay Alain           A 35.0 35.5
    Vachon Jean              P 40.0 22.75
    Lapalme Justin           O 40.0 15.75
    Deschenes Sylvie         P 35.0 25.0
    Lachance Carl            O 37.5 18.0
    Labonte Chantal          P 40.0 20.0
    Doucet Michel            A 40.0 33.75
    Desjardins Alex          P 35.0 25.0
    Tardif Guy               A 40.0 28.5
    Clinclin Stephane        O 40.0 20.75
    Lafleur Marie            A 37.5 32.75
    Desbiens Robert          P 35.0 25.0
    Desautels Maryse         P 35.0 26.0
    St-germain guy           O 37.5 15.0
    Bourgeois Louis          A 37.5 29.0
    St-amour Flavie          P 40.0 25.0
    En tout cas merci pour vos réponses rapides

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Es-tu bien sûr d'avoir des tabulations après chaque nom dans ton fichier ? Il n'y en a pas dans ce que tu nous as recopié.
    Dans le cas contraire, le premier getline(fichier, ptrTabEmploye[i].nom, '\t') va tout lire jusqu'à la fin du fichier et toutes les autres lectures échoueront. Tu afficheras alors des valeurs laissées non initialisées.
    D'où l'importance de vérifier l'état du flux comme te l'a montré Pyramidev.

    Autre chose, ce & est de trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fichier >> &ptrTabEmploye[i].poste;
    Ceci va tenter de lire une chaîne de caractères et non un caractère seul. Ce ne sera pas forcément visible à cause de l'alignement des float qui suivent et du fait qu'un seul caractère est lu, mais il en reste que c'est faux et qu'un '\0' sera écrit où il faut pas.

    Et il ne faut pas oublier le '\n' à la fin de chaque ligne, sinon tes getline termineront de lire la ligne précédente et tu te retrouveras avec des noms débutant par ce '\n'.
    Dernière modification par Invité ; 05/03/2017 à 07h34.

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Winjerome a tout à fait raison, d'ailleurs, si tu ajoutes dans ta boucle d'affichage un cout << "---" << endl;, tu verras bien que tout ce qui s'affiche de "bien" le fait dans nom du premier élément.

    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
    Tremblay Alain           A 35.0 35.5
    Vachon Jean              P 40.0 22.75
    Lapalme Justin           O 40.0 15.75
    Deschenes Sylvie         P 35.0 25.0
    Lachance Carl            O 37.5 18.0
    Labonte Chantal          P 40.0 20.0
    Doucet Michel            A 40.0 33.75
    Desjardins Alex          P 35.0 25.0
    Tardif Guy               A 40.0 28.5
    Clinclin Stephane        O 40.0 20.75
    Lafleur Marie            A 37.5 32.75
    Desbiens Robert          P 35.0 25.0
    Desautels Maryse         P 35.0 26.0
    St-germain guy           O 37.5 15.0
    Bourgeois Louis          A 37.5 29.0
    St-amour Flavie          P 40.0 25.0   6.48975e-07 4.15672e+21
     
    ---
       4.0517e-11 3.62304e+07
     
    ---
       2.33105e-09 6.82401e-07
     
    ---
       6.33764e-10 4.11992e-11
     
    ---
       4.16548e-11 4.22301e-05
     
    ---
    Tu n'as donc pas une colonne délimitée par une tabulation, mais une colonne de taille fixe. Pour la lire, une possibilité est d'utiliser get :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    			constexpr int COL_SIZE = 26;
    			char buffer[COL_SIZE + 1];
    			fichier.get(buffer, COL_SIZE);
    			ptrTabEmploye[i].nom = buffer;
    Mais par contre, n'oublie pas aussi de sauter au préalable le fin de ligne, pour que le get suivnt soit prêt à redémarrer (avec un getline).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre chevronné
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Par défaut
    Outre les réponses apportées au-dessus, pourquoi ne pas utiliser les >> ?

    Tu crées 5 variables (2 string, 1 char et 2 float) et tu récuperes tes valeurs puisque tout est bien formaté dans ton fichier avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    string nom, prenom;
    char poste;
    float salaire1, salaire2;
     
    if (flux)
    {
       while (n-- >= 0)
       {
          cin >> nom >> prenom >> poste >> salaire1 >> salaire2;
          // Tu stockes ensuite ces variables ou tu as besoin
       }
    }
    Tu t'exoneres d'un quelconque retraitement derriere par ce biais.

  7. #7
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 510
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 510
    Par défaut
    Bonjour,

    Je viens de tester ton code sur un fichier dont le contenu est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Tremblay Alain	A 35.0 35.5
    Tremblay Bruce	B 53.0 55.3
    et ça marche très bien.

    Par contre, si j'ajoute 3 lignes vides dans le fichier, le programme affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Tremblay Alain A 35 35.5
     
     
    Tremblay Bruce B 53 55.3
     
     
     
     
     T 4.54474e+030 5.79556e+022
     
     n 2.84057e+020 2.69593e+017
     
     
    Au revoir!
    ce qui est normal, car ton programme considère qu'il y a autant d'employés que de lignes.
    Du coup, le flux fichier finit par se retrouver dans un état erroné, donc les appels à >> n'ont plus d'effet, donc les champs de ta structure Employe restent dans un état non initialisé puis, quand tu les affiches, cela donne des valeurs aléatoires.

    Pour localiser facilement ce genre de problème, il est préférable de faire un contrôle après chaque opération de lecture.
    Exemple un peu moche en attendant que tu voies les exceptions en C++ :
    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
        for (int i =0; i<nbEmp; i++)   //Met les données dans le tableau
         {
            getline(fichier, ptrTabEmploye[i].nom, '\t');
            if(!fichier) {
    	  cout << "Erreur de lecture du nom de l'employe numero " << i+1 << endl;
    	  break;
            }
            fichier >> ptrTabEmploye[i].poste;
            if(!fichier) {
    	  cout << "Erreur de lecture du poste de l'employe numero " << i+1 << endl;
    	  break;
            }
            fichier >> ptrTabEmploye[i].heures;
            if(!fichier) {
    	  cout << "Erreur de lecture de l'horaire de l'employe numero " << i+1 << endl;
    	  break;
            }
            fichier >> ptrTabEmploye[i].salHor;
            if(!fichier) {
    	  cout << "Erreur de lecture du salaire de l'employe numero " << i+1 << endl;
    	  break;
            }
          }
    Dans le cas de mon fichier avec des lignes vides à la fin, cela m'affiche bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur de lecture du nom de l'employe numero 3
    Edit : grillé par JolyLoic pour les lignes vides. J'ai mis du temps à écrire mon poste à cause des tests en parallèle.

  8. #8
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2013
    Messages : 72
    Par défaut
    Vous pourriez quand même lui expliquer ce que c'est que ces trucs bizarres

    1.35632e-019 1.75442e-019
    o 1.84946e+031 3.03345e+032 …


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

Discussions similaires

  1. Réponses: 31
    Dernier message: 14/01/2014, 18h09
  2. Réponses: 7
    Dernier message: 27/03/2008, 00h23
  3. enregistrer un fichier texte dans sql server
    Par nezha1977 dans le forum ASP
    Réponses: 1
    Dernier message: 27/12/2007, 19h46
  4. Réponses: 5
    Dernier message: 17/12/2007, 17h50
  5. Réponses: 1
    Dernier message: 15/06/2006, 18h01

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