Pour chaque caractère de la chaîne


229

Comment pourrais-je faire une boucle for sur chaque caractère d'une chaîne en C ++?


9
Quel genre de ficelle? C-string, ou std::string?
Mysticial

Il est lu dans un fichier texte, donc je suppose std ::
Jack Wilsdon

4
Quel genre de personnage? char, Point de code Unicode, grappe de graphèmes étendue?
Philipp

Duplication possible de Comment puis-je parcourir une chaîne et connaître également l'index (position actuelle)? . Ne vous inquiétez pas de la indexpartie des réponses.
2014

Réponses:


418
  1. Faire une boucle à travers les caractères de a std::string, en utilisant une boucle for basée sur une plage (c'est de C ++ 11, déjà pris en charge dans les versions récentes de GCC, clang et VC11 beta):

    std::string str = ???;
    for(char& c : str) {
        do_things_with(c);
    }
  2. Parcourant les caractères d'un std::stringavec des itérateurs:

    std::string str = ???;
    for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
        do_things_with(*it);
    }
  3. En boucle à travers les personnages d'un std::stringavec une boucle for-old-fashioned:

    std::string str = ???;
    for(std::string::size_type i = 0; i < str.size(); ++i) {
        do_things_with(str[i]);
    }
  4. Boucle à travers les caractères d'un tableau de caractères à terminaison nulle:

    char* str = ???;
    for(char* it = str; *it; ++it) {
        do_things_with(*it);
    }

4
@Robinson: C'est une hypothèse erronée. Une hypothèse très erronée. En outre, "caractère" a tellement de significations différentes, il est préférable d'éviter strictement le terme.
Puppy

6
@Robinson: "std :: string est UTF8 (supposé être) " Depuis quand?!
Courses de légèreté en orbite le

2
Eh bien, OK, il n'a pas d'encodage, cependant étant donné l'ubiquité d'utf8 maintenant (en particulier sur le Web) et le fait que l'on puisse vouloir un seul encodage cohérent dans un pipeline ou une application, pour la base de cette discussion, mon std :: strings sont tous utf8: p.
Robinson

4
@Robinson: Et toutes les miennes sont traitées sans encodage car je ne programme pas dans un domaine accessible aux utilisateurs (c'est-à-dire qu'il n'y a pas de chaînes destinées à être rendues aux humains). Si vous voulez parler des encodages de caractères, vous devez parler d'une abstraction de niveau supérieur std::string , qui n'est qu'une série d'octets.
Courses de légèreté en orbite le

1
aussi, les cas 2 et 3 sont un bon exemple où vous pouvez / devez utiliser "auto"
galois

29

Une boucle for peut être implémentée comme ceci:

string str("HELLO");
for (int i = 0; i < str.size(); i++){
    cout << str[i];
}

Cela imprimera la chaîne caractère par caractère. str[i]renvoie le caractère à l'index i.

S'il s'agit d'un tableau de caractères:

char str[6] = "hello";
for (int i = 0; str[i] != '\0'; i++){
    cout << str[i];
}

Fondamentalement, au-dessus de deux, deux types de chaînes sont pris en charge par c ++. La seconde est appelée chaîne c et la première est appelée chaîne std ou (chaîne c ++). Je suggérerais d'utiliser une chaîne c ++, beaucoup plus facile à gérer.


24

En C ++ moderne:

std::string s("Hello world");

for (char & c : s)
{
    std::cout << "One character: " << c << "\n";
    c = '*';
}

En C ++ 98/03:

for (std::string::iterator it = s.begin(), end = s.end(); it != end; ++it)
{
    std::cout << "One character: " << *it << "\n";
    *it = '*';
}

Pour l'itération en lecture seule, vous pouvez utiliser std::string::const_iteratoren C ++ 98 et for (char const & c : s)ou simplement for (char c : s)en C ++ 11.


Voici quelques options pour les compilateurs avec prise en charge partielle de C ++ 11: pastebin.com/LBULsn76
Benjamin Lindley

@BenjaminLindley: Merci! autoest toujours une bonne idée. Lors de son utilisation, la distinction entre begin()et cbegin()devient pertinente.
Kerrek SB

2
quel est le rôle de la référence dans char ici ( char & c)? Est-ce juste pour permettre la modification de la valeur du caractère dans le cas où cela serait nécessaire?
LunaticSoul

11

Voici une autre façon de le faire, en utilisant l'algorithme standard.

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
   std::string name = "some string";
   std::for_each(name.begin(), name.end(), [] (char c) {
      std::cout << c;
   });
}

Nous avons l'année 2018, donc cela devrait être la bonne réponse.
rwst

7
const char* str = "abcde";
int len = strlen(str);
for (int i = 0; i < len; i++)
{
    char chr = str[i];
    //do something....
}

4
(Commentaire obsolète, qui est probablement toujours pertinent pour l'OP :) Il n'est pas considéré comme une bonne forme à utiliser strlendans la condition de boucle, car il nécessite une opération O (n) sur la chaîne pour chaque itération, ce qui rend la boucle entière O (n ^ 2) dans la taille de la chaîne. strlendans la boucle peut être appelée si la chaîne change pendant la boucle, mais doit être réservée aux cas où elle est réellement requise .
Magnus Hoff

@MagnusHoff: Ouaip, Schlemiel le Peintre lève de nouveau sa tête laide.
Fred Larson

J'ai édité ma réponse. Magnus tu as raison, oups utilise foreach en c # depuis quelques années;)
demoncodemonkey

Vous devez cependant toujours utiliser strlen () en dehors de la boucle de préférence au test de null à chaque itération.
mckenzm

4

Je ne vois aucun exemple utilisant une plage basée sur une boucle avec une "chaîne c".

char cs[] = "This is a c string\u0031 \x32 3";

// range based for loop does not print '\n'
for (char& c : cs) {
    printf("%c", c);
}

exemple non lié mais int array

int ia[] = {1,2,3,4,5,6};

for (int& i : ia) {
    printf("%d", i);
}

1

Pour C-string ( char []), vous devriez faire quelque chose comme ceci:

char mystring[] = "My String";
int size = strlen(mystring);
int i;
for(i = 0; i < size; i++) {
    char c = mystring[i];
}

Car std::stringvous pouvez utiliser str.size()pour obtenir sa taille et itérer comme l'exemple, ou vous pouvez utiliser un itérateur:

std::string mystring = "My String";
std::string::iterator it;
for(it = mystring.begin(); it != mystring.end(); it++) {
    char c = *it;
}

1
for (int x = 0; x < yourString.size();x++){
        if (yourString[x] == 'a'){
            //Do Something
        }
        if (yourString[x] == 'b'){
            //Do Something
        }
        if (yourString[x] == 'c'){
            //Do Something
        }
        //...........
    }

Une chaîne est essentiellement un tableau de caractères, vous pouvez donc spécifier l'index pour obtenir le caractère. Si vous ne connaissez pas l'index, vous pouvez le parcourir comme le code ci-dessus, mais lorsque vous faites une comparaison, assurez-vous d'utiliser des guillemets simples (qui spécifient un caractère).

En dehors de cela, le code ci-dessus est explicite.


-1

vous pouvez obtenir tous les caractères d'une chaîne en utilisant la fonction at de la bibliothèque de chaînes, comme je l'ai fait comme ça

string words;
    for (unsigned int i = 0; i < words.length(); i++)
        {
            if (words.at(i) == ' ')
            {
                spacecounter++;    // to count all the spaces in a string
                if (words.at(i + 1) == ' ')
                {
                    i += 1;
                }

ce n'est qu'un segment de mon code, mais le fait est que vous pouvez accéder aux caractères par stringname.at(index)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.