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

Langage C++ Discussion :

Découpage d'une chaine de caractères avec istringstream : segmentation fault.


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut Découpage d'une chaine de caractères avec istringstream : segmentation fault.
    Bonjour à tous.

    J'essaie de créer une fonction qui récupère des coordonnées dans un fichier texte. Le fichier texte étant conçu de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #{
    N1 -nombre- -nombre- -nombre- -nombre-
    N2 -nombre- -nombre- -nombre- -nombre-
    [...]
    Nx -nombre- -nombre- -nombre- -nombre-
    #}
    Je dois donc récupérer tout les nombres, bien entendu en ignorant la première et dernière ligne. Chaque ligne représentant donc les coordonnées des deux points d'un segments. J'ai donc rédigé la procédure suivante :
    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
     
    void setDataTable(float points[MAX][2] , string file)
    {
        ifstream f(file.c_str(), ios::in);
        string line, str;
        vector<string> result;
        int j=0;
        if (f)
        {
            while (! f.eof())
            {
                getline(f,line);
                istringstream iss(line);
                while (getline(iss, str, ' '))
                {
                    result.push_back(str);
                }
     
                for(int i=0; i < result.size(); i++)
                {
                    if (i == 1) points[j][0] = atof(result[i].c_str());
                    if (i == 2) points[j][1] = atof(result[i].c_str());
                    if (i == 3) points[j+1][0] = atof(result[i].c_str());
                    if (i == 4)
                    {
                        points[j+1][1] = atof(result[i].c_str());
                        j = j+2;
                    }
                }
     
            }
        }
        else
        {
            cerr << "setDataTable : can't read " << file << "." << endl;
        }
        cout << "Fin fonction setDataTable" << endl;
        f.close();
    }
    L'ennui, c'est que j'arrête pas d'avoir des segmentation faults, et j'arrive vraiment pas à résoudre ce problème. Je dois avoir raté quelque chose avec la lecture du fichier ou du istringstream. Une idée ?

    Merci d'avance pour votre réponse.

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    pour commencer, ce n'est pas while (f.eof()), mais while (getline(file, line)).
    En effet, eof indique si la derniere erreur est due à un eof, et getline peut ne pas marcher.

    on n'écrit pas ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                for(int i=0; i < result.size(); i++)
                {
                    if (i == 1) points[j][0] = atof(result[i].c_str());
                    if (i == 2) points[j][1] = atof(result[i].c_str());
                    if (i == 3) points[j+1][0] = atof(result[i].c_str());
                    if (i == 4)
                    {
                        points[j+1][1] = atof(result[i].c_str());
                        j = j+2;
                    }
                }
    Il y a un peu mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for(int i=0; i < result.size(); i++) {
        switch (i){
            case 1: points[j][0] = atof(result[i].c_str()); break;
            case 2: points[j][1] = atof(result[i].c_str()); break;
            case 3: points[j+1][0] = atof(result[i].c_str()); break;
            case 4:
                points[j+1][1] = atof(result[i].c_str());
                j = j+2;
                break;
        }
    }
    Et franchement plus clair:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {
        points[j][0] = atof(result[1].c_str());
        points[j][1] = atof(result[2].c_str());
        points[j+1][0] = atof(result[3].c_str());
        points[j+1][1] = atof(result[4].c_str());
        j = j+2;
    }
    Et la, subitement, tout devient clair.
    un vector commence à 0.

    Et tu peux même faire beaucoup mieux, en ne passant pas par result, mais directement par l'opérateur >> de istream.

    Autres remarques:
    • Controle l'erreur plutot que la validité: tu pourras quitter tout de suite, et le reste du code sera moins indenté. Avec cinq ressources, tu verras clairement la différence.
    • Il est inutile de fermer un stream déclaré en variable locale, le destructeur le fait pour toi.
    • Personnellement, je remplacerais la variable points par un vector<point<float>>, en définissant proprement point<float>.
      Après tout, pourquoi utiliser deux cases d'un tableau pour désigner un objet unique (un point)?


    Voici comment j'écrirai ta fonction (en gardant ton interface).

    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
     void setDataTable(float points[MAX][2] , string filename) {
        ifstream file(filename.c_str();
     
        if (!file) {
            cerr << "setDataTable : can't read " << filename << "." << endl;
    		throw std::runtime_error("file not opened: "+filename);
    	}
     
        string line;
        int j=0;
    	while (getline(file,line)) {
    		istringstream iss(line);
    		iss >> points[j][0] >> points[j][1] >> points[j+1][0] >> points[j+1][1]
    		j+=2
        }
        cout << "Fin fonction setDataTable" << endl;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Je viens d'essayer ton programme. On dirait que c'est pas ça : je débouche encore sur une segmentation fault. :/

    Par contre en effet, le code est plus lisible et bien plus propre.

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Avec un code clair, tu vois mieux que le problème ne vient pas de la.

    Pour moi, la cause, c'est d'avoir un tableau (dont les tailles ne sont pas spécifiables) en argument d'une fonction.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Bon, j'ai essayé de refaire avec une classe point. Ça me donne le code suivant.

    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
     
    void setDataTable(point p[MAX] , string filename)
    {
       ifstream file(filename.c_str());
       string str;
       vector<string> result;
     
       if (!file)
       {
           cerr << "setDataTable : can't read " << filename << "." << endl;
           throw std::runtime_error("file not opened: "+ filename);
       }
     
       string line;
       int j=0;
       while (getline(file,line))
       {
           istringstream iss(line);
           while(getline(iss,str))
           {
               result.push_back(str);
           }
           p[j].setX(atof(result[1].c_str()));
           p[j].setY(atof(result[2].c_str()));
           p[j+1].setX(atof(result[3].c_str()));
           p[j+1].setY(atof(result[4].c_str()));
           j=j+2;
       }
       cout << "Fin fonction setDataTable" << endl;
     
    }
    J'ai encore une segmentation fault (décidément, quand ça veut pas, ça veut pas). Sachant que je suis obligé de mettre un tableau en paramètre je crois, sinon je vois pas comment faire. Je pourrais essayer avec un vector remarque. Une idée ,

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Pourquoi tu as remis atof?
    Cette fonction comprends un "undefined behaviour" quand la donnée n'est pas un float.
    Ma solution ignore les blancs, les retours chariots, les tabulations, etc.

    supposant la classe Point, ta fonction pourrait avoir pour signature void loadDataTable(std::string const& filename, std::vector<point>& points).
    Voire mieux, si tu utilises les itérateurs d'insertion (comme std::insert_iterator)

    En reprenant l'interface de std::copy, ca donnerait
    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
    template<class OutputIt>
    OutputIt loadDataTable(std::string const& filename, OutputIt output) {
        ifstream file(filename.c_str();
     
        if (!file) {
            throw std::runtime_error("file not opened: "+filename);
        }
     
        string line;
        while (getline(file,line)) {
            istringstream iss(line);
            point p1, p2;
            iss >> p1.x >> p1.y >> p2.x >> p2.y;
            *(output++) = p1;
            *(output++) = p2;
        }
        return output;
    }
    Et la, tu n'as même plus besoin de savoir que la classe est un vector, une liste ou un set. (tant qu'elle à une fonction insert compatible avec point).
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    J'ai retiré les atof comme demandé.

    Après quelque tests, je pense avoir trouvé le vrai problème : j'ai remarqué qu'on dirait que mes variables prennent pas les valeurs au dessus de 6 millions. Pourtant mes attributs pour la classe point sont de type float. Avec ce 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
    void setDataTable(point p[], string filename)
    {
       ifstream file(filename.c_str());
       string str, nom_motif;
       double x1, y1, x2, y2;
     
       if (!file)
       {
           cerr << "setDataTable : can't read " << filename << "." << endl;
           throw std::runtime_error("file not opened: "+ filename);
       }
     
       string line;
       int j=0;
       while (getline(file,line))
       {
           istringstream iss(line);
           cout << line << endl;
           //IlvPrint ("lecture_trace_motifs_lambert2e_full %s",FIELDBUFFER);
     
           iss >> nom_motif;
           if (nom_motif[0]=='#' || nom_motif[0]==' ') continue;
           iss >> x1;
           iss >> y1;
           iss >> x2;
           iss >> y2;
           cout << x1 << " " << y1 << endl;
           cout << x2 << " " << y2 << endl;
           exit(0);
           /*
           p[j].setX(x1);
           p[j].setY(y1);
           p[j+1].setX(x2);
           p[j+1].setY(y2);
     
           cout << p[j].getX() << " " << p[j].getY() << endl;
           cout << p[j+1].getX() << " " << p[j+1].getY() << endl;
           j=j+2;*/
       }
       cout << "Fin fonction setDataTable" << endl;
     
    }
    En lisant mon fichier j’obtiens les résultats suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #(
    N0 696176 6878526 696190 6878768
    696176 6.87853e+06
    696190 6.87877e+06
    La seconde ligne est sensée être la lecture de la seconde ligne du fichier. Comme tu peux le voir, les nombres notés dans les variables y1 et y2 sont mal comptés, comme si un double ne pouvait pas grimper à plus de 6 millions. J'ai vraiment un gros doute là dessus.

    Je t'envoie l'intégralité de mon projet si tu veux faire des essais : http://www36.zippyshare.com/v/ZpkuyqEz/file.html
    Par contre c'est un tar.gz, et j'utilise des bibliothèques Qt. Tu auras sans doute besoin de linux et de Qt creator.

  8. #8
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Je ne vois pas de soucis dans ce programme : Les nombres au dessus de 6 millions sont bien gérés, il sont simplement affichés en mode scientifique. Tu peux forcer l'affichage sans mode scientifique (cout << fixed << 1e15 << endl)

    Après, par principe, je te demanderais bien pourquoi utiliser des floatau lieu d'utiliser des double, qui devraient être le choix par défaut sauf si on a des contraintes (d'utilisation mémoire en particulier) qui nous disent le contraire. Mais tu auras le même affichage.
    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.

  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    A mes yeux, ils sont bons.
    Par contre, un float est entaché de l'erreur flottante (possiblement faux à partir du 7° chiffre).
    Si tes nombres ne sont pas immenses, mais restent entiers, utilise plutot long
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je ne vois pas de soucis dans ce programme : Les nombres au dessus de 6 millions sont bien gérés, il sont simplement affichés en mode scientifique. Tu peux forcer l'affichage sans mode scientifique (cout << fixed << 1e15 << endl)

    Après, par principe, je te demanderais bien pourquoi utiliser des floatau lieu d'utiliser des double, qui devraient être le choix par défaut sauf si on a des contraintes (d'utilisation mémoire en particulier) qui nous disent le contraire. Mais tu auras le même affichage.
    En effet, "fixed" résout bien ce problème d'affichage.

    J'ai finalement pu résoudre mon problème de segmentation. L'erreur était en réalité toute bête : mon tableau n'était pas assez grand. J'ai oublié de multiplier sa taille par deux, vu qu'on a deux points par lignes. :p

    Merci encore pour votre aide et vos précieux conseils.

  11. #11
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Abandonne le tableau, autant que possible.
    Une référence sur un vecteur est tellement plus sure. (grace au .at(i) de C++11)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  12. #12
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Tiens bah justement, j'étais en train de faire ça, mais pas moyen d'afficher le contenu de mon vecteur avec des .at(i).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    vector<point> points;
     
        cout << "Fonction setDataTable" << endl;
        setDataTable(points, "../Phase6/IM/motifs_lambert93.txt");
        cout << "Lecture du tableau data"<< endl;
        for (int i=0; i>points.size(); i++)
        {
            std::cout << points.at(i).getX() << " " << points.at(i).getY() << std::endl;
        }
    J'ai beau le retourner dans tous les sens, y'a rien qui s'affiche dans la console de QtCreator. Y'a un moyen de faire en sorte que ça lise les coordonnées de mes points ?

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i=0; i>points.size(); i++)
    Rien ne te choque?

    Dans une boucle for, le corps est exécuté chaque fois que la condition (seconde expression) est vraie, ta condition est erronée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i=0; i<points.size(); i++) {
        std::cout << points.at(i).getX() << " " << points.at(i).getY() << std::endl;
    }
    Cela dit, il y a begin() et end(), et surtout, comme tu es en C++11 (ce qui est normal), le "range-base for loop":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto && p : points) {
        std::cout << p.getX() << " " << p.getY() << std::endl;
    }
    Et si tu définis operator <<(ostream&, point const&), ca peut même devenir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto && p : points) {
        std::cout << p << std::endl;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par leternel Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i=0; i>points.size(); i++)
    Rien ne te choque?

    Dans une boucle for, le corps est exécuté chaque fois que la condition (seconde expression) est vraie, ta condition est erronée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i=0; i<points.size(); i++) {
        std::cout << points.at(i).getX() << " " << points.at(i).getY() << std::endl;
    }
    Cela dit, il y a begin() et end(), et surtout, comme tu es en C++11 (ce qui est normal), le "range-base for loop":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto && p : points) {
        std::cout << p.getX() << " " << p.getY() << std::endl;
    }
    Et si tu définis operator <<(ostream&, point const&), ca peut même devenir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (auto && p : points) {
        std::cout << p << std::endl;
    }
    Oups !

    Bon, par contre il m'envoie balader avec auto.

    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
    ../Phase6/main.cpp: In function 'int main(int, char**)':
    ../Phase6/main.cpp:11:10: warning: 'auto' changes meaning in C++11; please remove it [-Wc++0x-compat]
    ../Phase6/main.cpp:11:15: error: expected unqualified-id before '&&' token
    ../Phase6/main.cpp:11:15: error: expected ';' before '&&' token
    ../Phase6/main.cpp:11:18: warning: the address of 'p' will always evaluate as 'true' [-Waddress]
    ../Phase6/main.cpp:11:20: error: expected ';' before ':' token
    ../Phase6/main.cpp:11:20: error: expected primary-expression before ':' token
    ../Phase6/main.cpp:11:20: error: expected ')' before ':' token
    ../Phase6/main.cpp:11:20: error: expected primary-expression before ':' token
    ../Phase6/main.cpp:11:20: error: expected ';' before ':' token
    ../Phase6/main.cpp:11:18: error: label 'p' used but not defined
    make: *** [main.o] Error 1
    make: Leaving directory `/home/alexandre/Bureau/VISTA/Phase6-build-desktop-Qt_4_8_2_in_PATH__System__Release'
    14:35:39: The process "/usr/bin/make" exited with code 2.
    Error while building/deploying project Phase6 (target: Desktop)
    When executing step 'Make'
    Et le code sans auto en utilisant at marche pas non plus. Y'a quand même rien qui sors. Pourtant on à vérifié en affichant points.size() à l'écran : y'a du contenu. :/

  15. #15
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Active le mode C++11, ca ira mieux.

    Sinon, revient aux itérateurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (std::vector<Point>::const_iterator it = points.begin(), end = points.end() ;  it!=end; ++it) {
        std::cout << (it->getX()) << ' ' << (it->getY()) << std::endl;
    }
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  16. #16
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par leternel Voir le message
    Active le mode C++11, ca ira mieux.

    Sinon, revient aux itérateurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (std::vector<Point>::const_iterator it = points.begin(), end = points.end() ;  it!=end; ++it) {
        std::cout << (it->getX()) << ' ' << (it->getY()) << std::endl;
    }
    J'avais déjà essayé avec un itérateur comme ça. J'ai cette erreur à chaque fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ../Phase6/main.cpp: In function 'int main(int, char**)':
    ../Phase6/main.cpp:13:32: error: passing 'const point' as 'this' argument of 'float point::getX()' discards qualifiers [-fpermissive]
    ../Phase6/main.cpp:13:55: error: passing 'const point' as 'this' argument of 'float point::getY()' discards qualifiers [-fpermissive]
    J'ai essayé sans le "const_" aussi, mais rien ne s'affiche.

  17. #17
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Fais nous donc voir ta classe Point, et les éventuelles fonctions libres directement associées.
    Je suis sûr qu'il y a quelques améliorations à apporter (au minimum le respect de la constance)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  18. #18
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par leternel Voir le message
    Fais nous donc voir ta classe Point, et les éventuelles fonctions libres directement associées.
    Je suis sûr qu'il y a quelques améliorations à apporter (au minimum le respect de la constance)
    J'ai justement résolu l'erreur en ajoutant "const" à getX() et getY(). Par contre y'a toujours rien qui s'affiche quand je build.

    Voilà ma classe point :

    point.h
    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
    #ifndef POINT_H
    #define POINT_H
     
    class point
    {
        private:
            double x; //Coordonnées en abscisse
            double y; //Coordonnées en ordonnée
        public:
            point(); //Constructeur vide : le point est initialisé à l'origine.
            point(double, double); //Le point est initialisé aux coordonnées (x,y)
            float getX() const; //Renvoie la coordonnée en abscisse
            float getY() const; //Renvoie la coordonnée en ordonnée
            void setX(double); //Modifie la coordonnée en abscisse.
            void setY(double); //Modifie la coordonnée en ordonnée.
    };
     
    #endif // POINT_H
    point.cpp
    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
    #include "point.h"
     
    point::point(double xp, double yp) : x(xp), y(yp) //Constructeur
    {
     
    }
     
    point::point() : x(0), y(0) //Constructeur par défaut
    {
     
    }
     
    float point::getX() const
    {
        return x; //Renvoie x(abscisse)
    }
     
    float point::getY() const
    {
        return y; //Renvoie y(ordonnée)
    }
     
    void point::setX(double xp)
    {
        x = xp; //modifie x(abscisse)
    }
     
    void point::setY(double yp)
    {
        y = yp; //modifie y(ordonnée)
    }

  19. #19
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Je trouve très étrange d'avoir un champ double, et une fonction get retournant un float. Chez moi, ca provoque un warning pour "perte possible de données"

    A part ca, sans être parfaitement optimale (ni template), ta classe est plutot correcte.


    PS: On est bien d'accord, en plus de builder, tu exécutes le programme?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  20. #20
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par leternel Voir le message
    Je trouve très étrange d'avoir un champ double, et une fonction get retournant un float. Chez moi, ca provoque un warning pour "perte possible de données"

    A part ca, sans être parfaitement optimale (ni template), ta classe est plutot correcte.


    PS: On est bien d'accord, en plus de builder, tu exécutes le programme?
    Oui oui, le programme compile et s'exécute sans problème : je compile toujours avant d'exécuter. Après il y a peut être un soucis avec le compilateur ou alors j'ai raté quelque chose avec mon fichier .pro (je travaille en effet sous QtCreator).

    J'ai peut être oublié de modifier quelques petits trucs dans ma classe point quand je suis passé du float au double. Je rectifie ça.

    EDIT : J'ai essayé de faire un constructeur par recopie dans la classe point, et d'utiliser un élément de mon vecteur dans mon constructeur. Je débouche sur un crash envoyé par un signal "out_of_range" : pas d'erreur de compilation. Le compilateur reçoit le signal SIGABRT.

    Ci-contre le code du constructeur par recopie et le bout de code utilisé pour l'afficher. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //Constructeur par recopie.
    point::point(const point& p)
    {
        x = p.getX();
        y = p.getY();
    }
     
    //Le bout de code utilisé pour afficher un membre du vector points.
        point test(points.at(5));
        cout << test.getX() << " " << test.getY() << endl;
    EDIT2 : J'ai trouvé la vraie nature du problème.

    Quand j'affiche mon vecteur dans la fonction setDataTable, y'a aucun problème. Quand j'essaie de le faire dans le main par contre y'a rien qui s'affiche. On dirait que le vecteur se vide en sortant de la fonction. Faut que je trouve un moyen de résoudre ça.

    EDIT3 : Problème résolu ! Il suffisait juste de passer le vector par référence (avec un &).

    Merci encore pour l'aide.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Découpage d'une chaine de caractères
    Par fab3131 dans le forum MFC
    Réponses: 2
    Dernier message: 08/04/2006, 16h46
  2. Dégradé sur une chaine de caractères avec 3 a 4 couleurs
    Par avogadro dans le forum Composants VCL
    Réponses: 6
    Dernier message: 31/03/2006, 13h21
  3. Lecture d'une chaine de caractère avec fgets
    Par mayoouketchup dans le forum Langage
    Réponses: 9
    Dernier message: 22/12/2005, 16h17
  4. découpage d'une chaine de caractère
    Par lamojuli dans le forum ASP
    Réponses: 4
    Dernier message: 13/05/2004, 15h00
  5. Réponses: 2
    Dernier message: 06/12/2002, 07h50

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