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 :

Message d'erreur du compilateur quand j'utilise v.at() pour un vecteur


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Par défaut Message d'erreur du compilateur quand j'utilise v.at() pour un vecteur
    Bonjour,

    j'ai rempli un vector s1,j'ai ensuite compléter un attribut name=s1.at(2).

    Cela ne fonctionne pas très bien,le programme s’arrete. J’ai pourtant s1.size() qui est égale à 5.



    le message d'erreur dans le compilateur est:

    terminate called after throwing an instance of 'std::out_of_range'
    what(): vector::_M_range_check: __n (which is 2) >= this->size() (which is 1)

    Nom : Capture.JPG
Affichages : 1262
Taille : 43,8 Ko

    Nom : Capture1.JPG
Affichages : 540
Taille : 39,8 Ko

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par devdas94 Voir le message
    J’ai pourtant s1.size() qui est égale à 5.
    Comment le sais-tu?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par devdas94 Voir le message
    J’ai pourtant s1.size() qui est égale à 5.
    Et pourtant l'exécution indique très clairement une erreur où s1.size == 1.
    À choisir, c'est l'exécution que je crois.
    Donc vérifies d'abord ton fichier de données.
    Et vu ta boucle while, tu vas de toutes façons avoir une erreur après la lecture de la dernière ligne. Tester le flag eof n'est pas une façon correcte de vérifier qu'on ait fini la lecture.
    https://cpp.developpez.com/faq/cpp/?...igne-par-ligne
    https://cpp.developpez.com/faq/cpp/?...-de-la-lecture

    Sinon pour montrer du code et texte, autant le copier/coller plutôt que des images pixelisées..
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mai 2019
    Messages : 4
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Et pourtant l'exécution indique très clairement une erreur où s1.size == 1.

    .
    Voilà ce que m'affiche ma console :

    Je construis
    string_name_station
    la taille de s1 est 5
    A
    la taille de s1 est 5
    B
    la taille de s1 est 5
    C
    la taille de s1 est 5
    D
    la taille de s1 est 5
    E
    la taille de s1 est 5
    F
    la taille de s1 est 5
    G
    la taille de s1 est 5
    H
    la taille de s1 est 5
    I
    la taille de s1 est 5
    J
    la taille de s1 est 5

    la taille de s1 est 1 ------> le problème est ici,il prend en compte la dernière ligne de mon fichier qui possède une case vide.





    Il fallait ne pas prendre en compte la dernière ligne du coup j'ai ajouté :

    if(s1.size()>2) {
    ....
    }


    ET CA FONCTIONNE

    MERCI POUR TON AIDE !

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Mais, surtout, tu devrais corriger ta logique...

    Donc, la premiière chose à faire serait déjà de commencer par utiliser les possibilités qui sont apparues en C++11 (cela fait quand même déjà 7 ans !!!), qui permettent -- entre autres -- de fournir le nom du fichier à ouvrir sous forme de std::string.

    L'ouverture du fichier peut désormais prendre une forme "aussi simple" que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void MaClass::readStations(std::string const & filename){
        std::ifstream entree(filename);
    }
    La deuxième chose à faire, c'est de se rendre compte que la classe std::ifstream est implicitement convertible en booléen : tant que l'instance de std::ifstream (entree) est dans un état cohérent, susceptible de permettre l'extraction d'une information, un test aussi simple que if(entree) renverra true.

    Pour être précis, ce test renverra true aussi longtemps que le bit de contrôle goodbite (qui passe à false dés qu'un bit d'erreur passe à true) vaudra trueC'est cool, car on peut se dire que, une fois que le fichier a été ouvert, si ce test renvoie false, c'est qu'il y a un problème contre lequel le développeur ne peut absolument pas se prémunir, qu'il faut donc quitter la fonction en cours (car elle ne pourra de toutes façons rien faire pour corriger le problème) et qu'il sera sûrement plus sage de laisser planter purement et simplement l'application si aucune solution suffisante n'est apportée "dans les fonctions appelantes".

    Tout de suite après avoir ouvert le fichier, nous pouvons donc provoquer le lancement d'une exception si l'instance de notre fichier (entree dans le cas présent) n'est pas prète à subir une extraction. Cela se ferait sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void MaClass::readStations(std::string const & filename){
        std::ifstream entree(filename); // on ouvre le fichier
        if(! entree){ // si le fichier n'est pas valide
            throw std::runtime_error("unable to open the requested file");
         // si le code arrive ici, le fichier a été correctement ouvert.
    }
    La troisième chose à faire, c'est d'observer le prototype de la fonction std::getline. En le simplifiant (parce que c'est une fonction template, qui utilise utilise des classes templates à rallonges et à charnières ), ce prototype prend la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::istream & getline(std::istream & input, std::string & str, char delim)
    Ce prototype nous permet de nous rendre compte que la fonction std::getline renvoie une référence sur le flux dont elle vient d'extraire une ligne (et dont elle aura placé le contenu dans str) délimité par le caractère delim. Et ca, c'est cool!!!

    Parce que cela veut dire que l'on peut tester le retour de std::getline pour nous assurer, après la tentative d'extraction, que le flux est toujours "en état" de permettre une extraction "supplémentaire". Et cela implique que l'on peut donc utiliser le retour de cette fonction comme ... condition devant être respectée pour rentrer "une fois de plus" dans une boucle.

    En effet, la condition que tu as placée while(!entree.eof()) pose un sérieux problème, dans le sens où la fonction membre eof() ne renvoie true qu'une fois que la fin de fonction a été dépacée; c'est à dire, une fois que l'on a tenté d'extraire "une donnée supplémentaire" alors que la fin du fichier avait été atteinte.

    On peut donc terminer l'écriture de la fonction en lui donnant une forme proche de
    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
    void MaClass::readStations(std::string const & filename){
        std::ifstream entree(filename); // on ouvre le fichier
        if(! entree){ // si le fichier n'est pas valide
            throw std::runtime_error("unable to open the requested file");
         // si le code arrive ici, le fichier a été correctement ouvert.
         std::vector<std::string> stringTab; // je trouve ce nom plus compréhensible que "s1" ;)
         std::string temp;
         while(std::getline(entree, temp)){ // tant que le flux reste valide après extraction d'une ligne
             stringTab = split(temp, ","); // j'espère que split fait correctement son travail :-$
             /* arrivé ici, stringTab contient toutes les "sous chaînes" de caractères que contenait temp
              * Il faudra juste s'assurer que le nombre de ces sous-chaines corresponde à ce que l'on s'attend
              * car autrement, c'est que le fichier a été corrompu
              * par exemple
              */
             if(stringTab.size()!=5) { // tu semble perçuadé qu'il y a au moins cinq sous-chaines
                                       //  Si ce n'est pas le cas, c'est qu'il y a un problème dans le fichier, et
                                       // qu'il vaut mieux arrêter le traitement
                 throw std::runtime_error("file corrupted, please correct it");
            }
            // on peut continuer le reste du traitement ici ;)
    }
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Avant toute chose : au lieu de perdre ton temps (et le notre) à créer un screenshot de ton code, pourrais tu en faire un copier / coller en l'entourant des balises [ CODE ] et [ / CODE ] (sans les espaces) qui apparaissent "comme par magie" lorsque tu clique sur le bouton en forme de # qui se trouve tout à fait à droite de l'une des lignes de boutons qui apparaissent au dessus de la zone d'édition

    Cela facilitera la vie de tout le monde, en nous permettant de le copier et de le coller à notre tour dans notre éditeur de textes favoris

    Ensuite, il faut savoir que c'est le propre de la fonction at: elle lance une exception si tu essaye d'accéder à un élément qui se trouve "en dehors" du nombre d'éléments que contient ton tableau (ou ta chaine de caractères).

    Si s1.at(XXX) lance une exception, quand s1 est de type std::vector<std::string> c'est "tout simplement" que s1 contient ... moins de XXX élément. Ou, plus précisément, que XXX représente un indice invalide par rapport au nombre d'éléments de ton tableau.

    Il ne faut pas oublier que les indices sont "nul based" en C++, ce qui fait que le premier élément se trouve à l'indice 0 et que l'indice 2 correspond au troisième élément.

    De toute évidence, si tu testais la taille de s1, tu te rendrais compte qu'elle est -- dans le meilleur des cas -- égale à deux GRAND MAXIMUM

    NOTA: Cette fonction est une pure abomination -- issue d'une époque où la programmation défensive régnait en maître -- du point de vue conceptuel, car elle traite une erreur de logique (tu essayes d'accéder à un élément de ton tableau qui n'existe pas) comme s'il s'agissait d'un événement contre lequel le développeur n'a aucune défense et qu'il ne peut donc que prendre en considération

    Elle ne devrait donc jamais être utilisée étant donné que c'est à toi de t'assurer que tu n'essayeras pas d'accéder à un élément "inexistant" au travers du reste de ta logique
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. [Débutant] WPF Erreur de build quand j'utilise Extended.Wpf.Toolkit.Plus.2.1.0
    Par intibnin dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 05/03/2014, 11h55
  2. Réponses: 0
    Dernier message: 13/12/2013, 11h10
  3. Réponses: 0
    Dernier message: 20/09/2012, 15h39
  4. Message d'erreur du compilateur que je ne comprends pas
    Par ram-0000 dans le forum Visual C++
    Réponses: 6
    Dernier message: 21/07/2010, 13h45
  5. [SBI BIRT] Erreur de transformation quand Birt utilise Allow Multiples values
    Par atee dans le forum SpagoBI
    Réponses: 1
    Dernier message: 23/04/2009, 17h09

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