Для кожного символу в рядку


229

Як я можу зробити цикл для кожного символу рядка в C ++?


9
Яка струна? C-рядок, або std::string?
Містичний

Він читається у текстовому файлі, тому я припускаю, що std ::
Jack Wilsdon

4
Який характер? char, Кодова точка Unicode, розширений кластер графеми?
Філіп

Можливий дублікат Як я можу повторити рядок, а також знати індекс (поточна позиція)? . Не турбуйтеся про indexчастину відповідей.
jww

Відповіді:


417
  1. Перебір з персонажами з std::string, використовуючи діапазон на основі для циклу (це з C ++ 11, вже підтримується в останніх версіях 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зі старомодним циклом:

    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
@Robinson: Це помилкове припущення. Дуже помилкове припущення. Також "персонаж" має стільки різних значень, краще терміново уникати цього терміна.
Щеня

6
@Robinson: "std :: string - це UTF8 (вважається, що є) " З тих пір ?!
Гонки легкості по орбіті

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

4
@Robinson: І всі мої трактуються як не кодуючі, тому що я не програмую в домені, орієнтованому на користувача (тобто немає рядків, призначених для надання людині). Якщо ви хочете поговорити про кодування символів, вам потрібно поговорити про абстракцію вищого рівня на вершині std::string , що є лише рядом байтів.
Гонки легкості по орбіті

1
також, випадки 2 і 3 є хорошим прикладом того, де можна / слід використовувати "авто"
166

29

Цикл циклу може бути реалізований так:

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 string, а перша називається std string або (c ++ string). Я б запропонував використовувати рядок 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()стає актуальною.
Керрек СБ

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
(Застарілий коментар, який, ймовірно, актуальний для ОП :) Це не вважається хорошою формою для використання strlenв умовах циклу, оскільки для нього потрібна операція O (n) для рядка для кожної ітерації, що робить весь цикл O (n ^ 2) у розмірі рядка. strlenв режимі циклу може бути викликано, якщо рядок змінюється під час циклу, але він повинен бути зарезервований для тих випадків, коли це фактично потрібно .
Магнус Гофф

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

Я відредагував свою відповідь. Магнус, ти маєш рацію,
ооп

Однак ви все ж повинні використовувати strlen () поза циклом, віддаючи перевагу тестуванню на null в кожній ітерації.
mckenzm

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

String - це в основному масив символів, тому ви можете вказати індекс для отримання символу. Якщо ви не знаєте індексу, ви можете провести цикл через нього, як у наведеному вище коді, але коли ви робите порівняння, переконайтеся, що ви використовуєте одинарні лапки (яка визначає символ).

Крім цього, вищезгаданий код не пояснює себе.


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