2012-02-24 3 views
137

Как бы сделать цикл for для каждого символа в строке на C++?Для каждого символа в строке

+4

Какие строки? C-string или 'std :: string'? – Mysticial

+0

Он читается в текстовом файле, поэтому я принимаю std :: –

+3

Какой персонаж? 'char', кодовая точка Unicode, расширенный кластер графем? – Philipp

ответ

268
  1. Looping через characters о наличии std::string, с использованием диапазона на основе для цикла (это от C++, 11, ALR Eady поддерживается в последних версиях GCC, грохотом и VC11 бета):

    std::string str = ???; 
    for(char& c : str) { 
        do_things_with(c); 
    } 
    
  2. Перебор характерами std::string с итераторов:

    std::string str = ???; 
    for(std::string::iterator it = str.begin(); it != str.end(); ++it) { 
        do_things_with(*it); 
    } 
    
  3. Перебор характерами std::string с старомодный для цикла:

    for(std::string::size_type i = 0; i < str.size(); ++i) { 
        do_things_with(str[i]); 
    } 
    
  4. Перебор характерами нуль-TERMI NAT, массив символов:

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

Это несколько путает меня, учитывая, что std :: string - UTF8 (предполагается, что это так), поэтому кодирование возможно переменной длины. Вы итерируете через байты в строке или в символах? – Robinson

+0

'std :: string' является (определяется как) последовательность с нулевым символом объектов' char'. –

+4

@ Robinson: Это ошибочное предположение. Очень ошибочное предположение. Кроме того, «персонаж» имеет очень много разных значений, лучше всего избегать этого термина. – Puppy

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

(Устаревший комментарий, который по-прежнему, вероятно, имеет отношение к OP :). Не считается хорошей формой использовать 'strlen' в условии цикла, так как для каждой итерации требуется операция O (n), что делает всю цикл O (n^2) в размере строки. 'strlen' в состоянии цикла может вызываться, если строка изменяется во время цикла, но должна быть зарезервирована для случаев, когда она фактически * требуется *. –

+0

@MagnusHoff: Yup, [Schlemiel the Painter] (http://en.wikipedia.org/wiki/Schlemiel_the_Painter%27s_algorithm) снова возвращает свою уродливую голову. –

+0

Я отредактировал свой ответ. Magnus вы правы, oops использовали foreach в C# последние пару лет;) – demoncodemonkey

17

для цикла может быть реализована следующим образом:

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

Это будет печатать строку посимвольно. str[i] возвращает символ по индексу i.

Если это массив символов:

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

В основном выше два являются два типа строк, поддерживаемых с ++. Вторая называется c-строкой, а первая называется std string или (C++ string). Я бы предложил использовать строку C++, очень удобную для обработки.

18

В современном C++:

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

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

В C++ 98/03:

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

только для чтения итерации, вы можете использовать std::string::const_iterator в C++ 98 и for (char const & c : s) или просто for (char c : s) в C++ 11.

+0

Вот пара вариантов для компиляторов с частичной поддержкой C++ 11: http://pastebin.com/LBULsn76 –

+0

@BenjaminLindley: Спасибо! 'auto' - это всегда хорошая идея. При его использовании различие между 'begin()' и 'cbegin()' становится актуальным. –

+0

Какова роль ссылки в char здесь ('char & c')? Это просто, чтобы разрешить изменение значения символа в случае, когда это необходимо? – LunaticSoul

0

Для C-строки (char []), вы должны сделать что-то вроде этого:

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

Для std::string вы можете использовать str.size(), чтобы получить его размер и итерацию, как, например, или может использовать итератор:

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

Строка в основном массив символов, поэтому вы можете указать индекс, чтобы получить характер. Если вы не знаете индекс, то вы можете пропустить его, как приведенный выше код, но когда вы делаете сравнение, убедитесь, что вы используете одинарные кавычки (который указывает символ).

Кроме этого, приведенный выше код сам по себе поясняет.

-2

вы можете получить каждый символ в строке, используя в функции струнной библиотеки, как я сделал это, как этот

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

это просто отрезок моего кода, но дело в том, вы можете получить доступ символов по stringname.at(index)

2

Вот еще один способ сделать это, используя стандартный алгоритм.

#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; 
    }); 
} 
1

Я не вижу примеров, используя диапазон, основанный на цикле с «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); 
} 

не связаны, но целочисленный массив Пример

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

for (int& i : ia) { 
    printf("%d", i); 
} 
Смежные вопросы