Для каждого символа в строке


230

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


9
Что за строка? C-строка или std::string?
Мистик

Он читается из текстового файла, поэтому я предполагаю, что std ::
Джек Уилсдон

4
Что за персонаж? char, Кодовая точка Unicode, расширенный кластер графем?
Филипп

Возможный дубликат Как я могу перебрать строку, а также узнать индекс (текущую позицию)? , Не беспокойтесь о indexроли в ответах.
jww

Ответы:


418
  1. Циклический просмотр символов a std::stringс использованием цикла for на основе диапазона (это из C ++ 11, уже поддерживается в последних выпусках GCC, clang и бета-версии 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 str = ???;
    for(std::string::size_type i = 0; i < str.size(); ++i) {
        do_things_with(str[i]);
    }
  4. Цикл по символам массива символов с нулевым символом в конце:

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

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

6
@Robinson: "std :: string - это UTF8 (предполагается) " С каких пор ?!
Гонки легкости на орбите

2
Ну, ладно, у него нет кодировки, однако, учитывая повсеместность utf8 сейчас (особенно в сети) и тот факт, что можно использовать единую согласованную кодировку для всего конвейера или приложения, в качестве основы для моего обсуждения мои std :: strings все utf8: с.
Робинсон

4
@Robinson: И все мои обрабатываются как не кодирующие, потому что я не программирую в пользовательской области (то есть, нет строк, предназначенных для визуализации людьми). Если вы хотите поговорить о кодировке символов, вам нужно поговорить о высокоуровневой абстракции поверх всего std::string , что является просто серией байтов.
Гонки легкости на орбите

1
Кроме того, случаи 2 и 3 являются хорошим примером того, где вы можете / должны использовать «авто»
галуа

29

Цикл for может быть реализован так:

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 ++. Второй называется строкой c, а первый называется строкой std или (строкой c ++). Я бы предложил использовать строку c ++, очень простую в обращении.


24

В современном 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.


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

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

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

11

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

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

У нас 2018 год, так что это должен быть правильный ответ.
rwst

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

4
(Устаревший комментарий, который все еще, вероятно, актуален для OP :). Это не считается хорошей формой для использования strlenв условии цикла, поскольку для каждой итерации требуется операция O (n) над строкой, что делает весь цикл O (n). ^ 2) по размеру строки. strlenв цикле условие может быть вызвано, если строка изменяется во время цикла, но должно быть зарезервировано для случаев, когда это действительно требуется .
Магнус Хофф

@MagnusHoff: Да, Шлемель Художник снова поднимает свою уродливую голову.
Фред Ларсон

Я отредактировал свой ответ. Магнус, ты прав, упс использовал foreach в c # последние пару лет;)
demoncodemonkey

Тем не менее, вы все равно должны использовать strlen () вне цикла, предпочитая проверять нулевое значение в каждой итерации.
Маккензм

4

Я не вижу примеров использования диапазона, основанного на цикле с "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

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

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

1

Для C-string ( 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;
}

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
        }
        //...........
    }

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

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


-1

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

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)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.