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 :

[fstream]Lecture d'un double à partir d'un fichier


Sujet :

C++

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut [fstream]Lecture d'un double à partir d'un fichier
    Bonjour,
    J'ai un fichier *.wkt contenant 1000 lignes sous cette forme : POINT(654875.345 68912.296)
    J'ai essayé d'écrire une fonction qui permet de lire chaque ligne, d'extraire les deux nombres (qui représentent des coordonnées) et de les mettre dans des objets Point que j'ai mis dans un vector.
    Dans la classe Point j'ai mis deux attributs de type double X et Y, en plus des getters et des setters.
    Le problème est que je ne peux pas lire les deux doubles. Lorsque j'affiche ce que le programme a lu, je trouve des valeurs aléatoires.
    Est-ce que quelqu'un a une idée de ce qui se passe ?
    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
    bool charger(char* nom, vector<Point> &liste, int taille){ //taille = 1000 : nombre de lignes du fichier
            ifstream fin;
            fin.open(nom);
     
            //Vérifier que le fichier est ouvert sans problèmes
            if(!fin){
                    cout<<"Probleme a l'ouverture du fichier"<<endl;
                    return false;
     
            }// Fin if
     
            // Saisie des coords dans les objets Point
            double x, y;
            char c;
            for(int j=0; j<taille; j++){
                // On saute la chaîne 'POINT('
                fin.seekg(6,ios_base::cur);
     
                // On prend le X, le Y et le caractère ')' à la fin de chaque ligne j
                fin>>x>>y>>c;
                cout<<x<<endl<<y<<endl<<c<<endl; //les valeurs de x et y ne sont pas les bonnes. Par contre dans c il y a ')' comme prévu
                // On met le X et le Y dans le point j de la liste
                liste.assign(1,Point(x,y));
                cout<<liste[j].getX()<<endl<<liste[j].getY()<<endl;//ça me donne des valeurs encore différentes
     
            }// Fin for
     
            // Fermeture du stream
            fin.close();
     
            // Valeur retournée par la fonction
            return true;
     
    }// Fin charger(...)

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Il se passe que le cin n'arrive pas à lire ce que vous demander.
    Je vous conseille d'utiliser des floats juste pour essai ... de plus je conseille aussi de faire une surcharge de l'operateur << dans la classe Point afin de rendre le code plus simple (et plus logique C++)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Bonjour :

    http://www.cplusplus.com/reference/stl/vector/assign/

    vector::assign
    Assigns new content to the vector object, dropping all the elements contained in the vector before the call and replacing them by those specified by the parameters:
    Donc la taille de ton vector vaut perpétuellement 1, et l'accès au vector "liste[j]" va taper dans une zone de mémoire non initialisée. (d'ou les valeurs aléatoires)

    Il me semble que tu veux utiliser vector::push_back() ici, pas vector::assign().

    Edit : Aussi, je ne pense pas que ce soit correct le coup du "fin.seekg (6,ios_base::cur);". Ca marche probablement pour la première ligne, mais ensuite il faut tenir compte du fait que chaque ligne se termine par un caractère eol ("\n")

  4. #4
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Je vous remercie de vos réponses.

    Même en déclarant x et y comme des float je n'arrive pas à lire correctement les nombres. Cette fois, il me donne des entiers en arrondissant les valeurs du fichier pour la première ligne et des valeurs erronées pour les autres.

    Et j'ai ajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fin.seekg(1,ios_base::cur);
    (après avoir changé assign() par push_back()) à la fin de la boucle for pour lire le caractère eol mais ça n'a rien changé

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Ca ne serait pas plus simple à parser si tu commeçais par extraire les lignes de texte (getline(fin, mystring), ou mystring est du type std::string). A partir de la, tu peux séparer le texte comme tu le souhaites, et utiliser std::stringstream pour faire la conversion des différents tokens dans leurs types respectifs).

    AU moins, ça te permettrais de debugger plus aisément
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Salut,

    yo_haha : Cette fois, il me donne des entiers en arrondissant les valeurs du fichier pour la première ligne et des valeurs erronées pour les autres.
    Attention! D'après microsoft :
    Point, structure : Représente une paire ordonnée de coordonnées x et y entières qui définit un point dans un plan à deux dimensions.
    Si tu veux utiliser des valeurs de type float ou double, il ne faut pas utiliser la structure 'System:: Drawing:: Point'
    Tu peut créer tes propres points, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct MesPoints { double x, y; }
    Bye

  7. #7
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Re Salut,

    J'ai remplacé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fin.seekg(6,ios_base::cur);
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fin >> c >> c >> c >> c >> c >> c;
    c'est pas élégant du tout mais ca permet à la fonction de fonctionner parfaitement sur mon PC!

    J'ai aussi rajouté la structure 'MonPoint' pour pouvoir créer des points à coordonnées 'double'.

    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
    struct MonPoint
    {
    	double x, y;
    };
     
    bool charger(char* nom, vector<MonPoint> &liste, int taille)	 //taille = 1000 : nombre de lignes du fichier
    {
        ifstream fin;
        fin.open(nom);
     
        //Vérifier que le fichier est ouvert sans problèmes
        if(!fin){
                cout<<"Probleme a l'ouverture du fichier"<<endl;
                return false;
     
        }// Fin if
     
        // Saisie des coords dans les objets Point
        double x, y;
        char c;
        for(int j=0; j<taille; j++){
    		MonPoint pt;
    		fin >> c >> c >> c >> c >> c >> c;	// C'est pas élégant mais du coup : bool charger( ... ) fonctionne!!
            // On prend le X, le Y et le caractère ')' à la fin de chaque ligne j
            fin >> x >> y >> c;
            cout<<x<<endl<<y<<endl<<c<<endl; //les valeurs de x et y ne sont pas les bonnes. Par contre dans c il y a ')' comme prévu
            // On met le X et le Y dans le point j de la liste
     
    		pt.x = x;
    		pt.y = y;
     
            liste.push_back(pt);
    		cout<<liste[j].x<<endl<<liste[j].y<<endl;//ça me donne des valeurs encore différentes
     
        }// Fin for
     
        // Fermeture du stream
        fin.close();
     
        // Valeur retournée par la fonction
        return true;
    }// Fin charger(...)*
    Pourquoi ça ne marchait pas avant : je ne sais pas!
    Pourquoi ça marche maintenant : je ne sais pas non plus!

    Mais ca marche : manifestement le fautif est Bon code.

  8. #8
    Membre régulier
    Inscrit en
    Novembre 2008
    Messages
    308
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 308
    Points : 90
    Points
    90
    Par défaut
    Merci pour le conseil Emmanuel.

    A bertry, je te remercie. Effectivement le seekg() posait des problèmes. Je l'ai retiré et les choses marchent beaucoup mieux. Par contre, le problème des valeurs qui sont prises du fichier en arrondi persiste !
    Sinon, pour la structure Point, je n'utilise pas le System:: Drawing:: Point. J'ai créé une classe Point avec des attributs et méthodes que j'ai déclaré moi-même (j'ai déclaré X et Y comme des doubles).

  9. #9
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Points : 827
    Points
    827
    Par défaut
    Oui yo_haha,
    Pour l'arrondi, Les valeurs qui s'affichent à l'écran sont arrondies, mais les valeurs qui sont dans le 'vector' sont celles qui sont dans le fichier ( le system les fait varier de + ou - 1 LSB, je ne sais pas pourquoi ).
    Si toutes tes valeurs n'ont que trois décimales après la virgule, comme dans l'exemple, trouve une fonction qui les arrondissent à 10-4 ou 10-5 et ce sera bon...

Discussions similaires

  1. Réponses: 10
    Dernier message: 07/12/2009, 17h00
  2. Réponses: 2
    Dernier message: 22/05/2009, 15h06
  3. Réponses: 8
    Dernier message: 12/02/2009, 16h20
  4. Réponses: 6
    Dernier message: 08/12/2008, 12h22
  5. Réponses: 23
    Dernier message: 14/08/2007, 14h39

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