web-dev-qa-db-fra.com

Récupère l'index de l'élément courant dans la boucle for basée sur la plage C ++

Mon code est le suivant:

std::cin >> str;
for ( char c : str )
    if ( c == 'b' ) vector.Push_back(i) //while i is the index of c in str

Est-ce faisable? Ou je devrai aller avec la boucle de la vieille école?

30
Shane Hsu

En supposant que str est un std::string ou autre objet avec stockage contigu:

std::cin >> str;
for (char& c : str)
    if (c == 'b') v.Push_back(&c - &str[0]);
20
Benjamin Lindley

Peut-être qu'il suffit d'avoir une variable i?

unsigned i = 0;
for ( char c : str ) {
  if ( c == 'b' ) vector.Push_back(i);
  ++i;
}

De cette façon, vous n'avez pas à modifier la boucle basée sur la plage.

32
Daniel Frey

La boucle de plage ne vous donnera pas l'index. Il a pour but d'abstraire de tels concepts et de vous laisser simplement parcourir la collection.

6
Karthik T

Ce que vous décrivez est connu comme une opération "chacun avec index" dans d'autres langues. En faisant une recherche rapide sur Google, il semble qu'en dehors de la `` boucle de la vieille école '', vous ayez des solutions plutôt compliquées impliquant des lambas C++ 0x ou peut-être des gemmes fournies par Boost.

EDIT: À titre d'exemple, voir ceci question

4
Ron Dahlgren

Vous pouvez utiliser lambdas en c ++ 11:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;


int main() {
    std::string str;
    std::vector<char> v;
    auto inserter = std::back_insert_iterator<decltype(v)>(v);

    std::cin >> str;
    //If you don't want to read from input
    //str = "aaaaabcdecccccddddbb";

    std::copy_if(str.begin(), str.end(), inserter, [](const char c){return c == 'b';});

    std::copy(v.begin(),v.end(),std::ostream_iterator<char>(std::cout,","));

    std::cout << "Done" << std::endl;

}
4
Joel