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 :

syntaxe while avec un itérateur


Sujet :

C++

  1. #1
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 200
    Par défaut syntaxe while avec un itérateur
    Bonjour.

    je m'initie au C++ et je rencontre un problème lors de la compilation d'un bout de 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
    std::ifstream fichier_lecture {"texte.txt"};
    std::string ligne {""};
     
    while (std::getline(fichier_lecture,ligne))
      {
        nb_ligne++;
        std::string::iterator it {std::find(std::begin(ligne),std::end(ligne),' ')};
        while (it != std::end(ligne))
        {
           ...
        }
         ...
      }
    }
    compile très bien

    alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    std::ifstream fichier_lecture {"texte.txt"};
    std::string ligne {""};
     
    while (std::getline(fichier_lecture,ligne))
      {
        nb_ligne++;
        while (std::string::iterator it {std::find(std::begin(ligne),std::end(ligne),' ')} != std::end(ligne))
        {
           ...
        }
         ...
      }
    }
    renvoie le message d'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    could not convert 'it' from 'std::__cxx11::basic_string<char>::iterator' to 'bool'
    Pourquoi, dans la deuxième version, le compilateur cherche-t-il à convertir mon itérateur en booléen?
    La condition du while reste bien une comparaison entre 2 itérateurs, non?

    Merci de votre aide.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 617
    Par défaut
    J'ai mis un temps à mettre le doigt dessus également :-)

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    while (std::string::iterator it {std::find(std::begin(ligne),std::end(ligne),' ')} != std::end(ligne))

    Tu ne peux pas déclarer une nouvelle variable au sein d'une condition while comme on le fait au début d'un for, par exemple. Par contre, il reste tout-à-fait possible de construire une instance anonyme d'un type (qui formera une xvalue). Et pour ce faire, il suffit de supprimer le symbole « it » seul au sein de ton expression.

    Ça compilera en l'état (ici, le corps de ta boucle est vide), par contre tu ne pourras pas faire référence à cet itérateur au sein de ta boucle et, donc, tu ne pourras pas le faire avancer non plus. Donc en l'état l'expression ne sert à rien, mais elle compile quand même.

  3. #3
    Membre confirmé

    Inscrit en
    Octobre 2003
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Octobre 2003
    Messages : 200
    Par défaut
    explication limpide!
    J'ai effectivement cru que l'on pouvait faire avec le while la même chose qu'avec le for.

    Merci beaucoup.

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 322
    Par défaut
    Malheureusement il manque à while la zone d'initialisation qui permet de déclarer localement des nouvelles variables dans for depuis toujours en C++, et dans if et switch depuis le C++17.

    En version for, il y a une façon redondante et une façon obfusquée de faire la chose
    Et c'est pas que la version redondante ne soit pas obfusquée non plus dans mon implémentation: https://godbolt.org/z/ocoWTT6x1

    Code c++ : 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
    #include <string_view>
    #include <algorithm>
    #include <print> // C++23
     
    void split_redondant(std::string_view s)
    {
        for (auto it = std::find(s.begin(), s.end(), '-'), old=s.begin()
        ; it != s.end()
        ; old=it+1, it = std::find(old, s.end(), '-'))
        {
            std::string_view sub(old, it);  // subview en C++26
            std::println("-> {}", sub);
        }
    }
     
    void split_obfusqué(std::string_view s)
    {
        for (auto it = s.begin(), old=s.begin()
        ; (it = std::find(old, s.end(), '-')) != s.end() // Tu vois l'affectation dégueulasse en plein milieu des parenthèses qui isolent le membre droit à tester?
        ; old=it+1)
        {
            std::string_view sub(old, it);  // subview en C++26
            std::println("-> {}", sub);
        }
    }


    Ca peut paraitre surprenant, mais je préfère utiliser for pour itérer et réserver while a des conditions complexes et non itératives.

    EDIT: la version obfusquée ne l'est pas assez, j'avais oublié std::exchange (une sorte de post-incrémentation avec une nouvelle valeur autre que l'ex+1). Ne faites pas ça à la maison.

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        for (auto it = s.begin(), old=s.begin()
        ; (it = std::find(std::exchange(old, it+1), s.end(), '-')) != s.end()
        ;)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 596
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 596
    Par défaut
    Salut à tous.

    Il y a surtout un problème de logique dans ton exemple.
    Tu retrouveras toujours le même premier espace et ta boucle ne progressera pas.
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    std::string::iterator it = std::begin(ligne);
     
    while (it != std::end(ligne))
    {
    	it = std::find(it, std::end(ligne), ' ');
     
    	if (it == std::end(ligne))
    		break;
     
        // Traitement de l'espace trouvé
        ...
     
    	++it;	// On avance après l'espace
    }

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

Discussions similaires

  1. Faire un while avec condition d'arrêt une durée
    Par schumi101 dans le forum Linux
    Réponses: 3
    Dernier message: 16/06/2006, 12h31
  2. [SQL] probleme de syntaxe sql avec php
    Par kaygee dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 05/06/2006, 14h32
  3. syntaxe requete avec parametres
    Par mike600river dans le forum C++Builder
    Réponses: 5
    Dernier message: 24/05/2006, 17h03
  4. [SQL] Dans un while avec fichier
    Par ozzmax dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 10/02/2006, 20h54
  5. [Syntaxe] Requêtes avec null
    Par Procto dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/07/2005, 16h10

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