Por cada caracter en cadena

229

¿Cómo haría un bucle for en cada carácter de la cadena en C ++?

Jack Wilsdon
fuente
99
¿Qué tipo de cuerda? C-string, o std::string?
Mysticial
Se lee en un archivo de texto, así que supongo que std ::
Jack Wilsdon
44
¿Qué tipo de personaje? char, Punto de código Unicode, clúster de grafema extendido?
Philipp
Posible duplicado de ¿Cómo puedo iterar a través de una cadena y también conocer el índice (posición actual)? . No te preocupes por la indexparte en las respuestas.
jww

Respuestas:

418
  1. Recorriendo los caracteres de a std::string, utilizando un bucle for basado en rango (es de C ++ 11, ya admitido en versiones recientes de GCC, clang y VC11 beta):

    std::string str = ???;
    for(char& c : str) {
        do_things_with(c);
    }
  2. Recorriendo los caracteres de a std::stringcon iteradores:

    std::string str = ???;
    for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
        do_things_with(*it);
    }
  3. Recorriendo los personajes de a std::stringcon un bucle for antiguo:

    std::string str = ???;
    for(std::string::size_type i = 0; i < str.size(); ++i) {
        do_things_with(str[i]);
    }
  4. Recorriendo los caracteres de una matriz de caracteres con terminación nula:

    char* str = ???;
    for(char* it = str; *it; ++it) {
        do_things_with(*it);
    }
R. Martinho Fernandes
fuente
44
@ Robinson: Esa es una suposición errónea. Una suposición muy defectuosa. Además, "personaje" tiene tantos significados diferentes, que es mejor evitar estrictamente el término.
Puppy
66
@Robinson: "std :: string es UTF8 (se supone que es) " ¿Desde cuándo?
ligereza corre en órbita el
2
Bueno, está bien, no tiene codificación, sin embargo, dada la ubicuidad de utf8 ahora (especialmente en la web) y el hecho de que uno podría desear una sola codificación consistente a través de una tubería o aplicación, para la base de esta discusión, mis cadenas std :: son todos utf8: p.
Robinson
44
@Robinson: Y todos los míos son tratados como sin codificación porque no estoy programando en un dominio orientado al usuario (es decir, no hay cadenas destinadas a ser prestados a humanos). Si desea hablar sobre codificaciones de caracteres, debe hablar sobre una abstracción de nivel superior std::string , que es solo una serie de bytes.
ligereza corre en órbita el
1
Además, los casos 2 y 3 son un buen ejemplo de dónde puede / debe usar "auto"
galois
29

Un bucle for puede implementarse así:

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

Esto imprimirá la cadena carácter por carácter. str[i]Devuelve el carácter en el índice i.

Si es una matriz de caracteres:

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

Básicamente, arriba de dos hay dos tipos de cadenas compatibles con c ++. El segundo se llama cadena c y el primero se llama cadena estándar o (cadena c ++). Sugeriría usar una cadena c ++, mucho más fácil de manejar.


fuente
24

En C ++ moderno:

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 = '*';
}

Para la iteración de solo lectura, puede usarla std::string::const_iteratoren C ++ 98 y / for (char const & c : s)o solo for (char c : s)en C ++ 11.

Kerrek SB
fuente
Aquí hay un par de opciones para compiladores con soporte parcial de C ++ 11: pastebin.com/LBULsn76
Benjamin Lindley
@BenjaminLindley: ¡Gracias! autoSiempre es una buena idea. Al usarlo, la distinción entre begin()y se cbegin()vuelve relevante.
Kerrek SB
2
¿Cuál es el papel de la referencia en char here ( char & c)? ¿Es solo para permitir la modificación del valor del personaje en caso de que sea necesario?
LunaticSoul
11

Aquí hay otra forma de hacerlo, utilizando el algoritmo estándar.

#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;
   });
}
0xBADF00
fuente
Tenemos el año 2018, así que esta debería ser la respuesta correcta.
rwst
7
const char* str = "abcde";
int len = strlen(str);
for (int i = 0; i < len; i++)
{
    char chr = str[i];
    //do something....
}
demoncodemonkey
fuente
44
(Comentario desactualizado, que probablemente todavía sea relevante para el OP :) No se considera una buena forma de usar strlenen la condición del bucle, ya que requiere una operación O (n) en la cadena para cada iteración, haciendo que todo el bucle O (n ^ 2) en el tamaño de la cadena. strlenen la condición de bucle se puede llamar si la cadena cambia durante el bucle, pero se debe reservar para los casos en que realmente se requiere .
Magnus Hoff
@MagnusHoff: Sí, Schlemiel el pintor vuelve a alzar su fea cabeza.
Fred Larson
He editado mi respuesta. Magnus tienes razón, ¡Uy, has estado usando foreach en C # durante los últimos años;)
demoncodemonkey
Sin embargo, aún debe usar strlen () fuera del ciclo en lugar de probar nulo en cada iteración.
mckenzm
4

No veo ningún ejemplo que use un rango basado en el bucle con una "cadena 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);
}

no relacionado pero ejemplo de matriz int

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

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

Para C-string ( char []) deberías hacer algo como esto:

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

Para std::stringusted puede utilizar str.size()para conseguir su tamaño y iterate como el ejemplo, o podría utilizar un iterador:

std::string mystring = "My String";
std::string::iterator it;
for(it = mystring.begin(); it != mystring.end(); it++) {
    char c = *it;
}
Tiago Pasqualini
fuente
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
        }
        //...........
    }

Una cadena es básicamente una matriz de caracteres, por lo tanto, puede especificar el índice para obtener el carácter. Si no conoce el índice, puede recorrerlo como el código anterior, pero cuando haga una comparación, asegúrese de usar comillas simples (que especifican un carácter).

Aparte de eso, el código anterior se explica por sí mismo.

casi un principiante
fuente
-1

puedes obtener todos los caracteres en una cadena usando la función at de la biblioteca de cadenas, como lo hice así

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;
                }

esto es solo un segmento de mi código, pero el punto es que puedes acceder a los caracteres por stringname.at(index)

Shuja Ul Hasan
fuente