Dizedeki her karakter için


230

C ++ dizesindeki her karakter için bir for döngüsü nasıl yapabilirim?


9
Ne tür bir ip? C-dizesi veya std::string?
Gizemli

Bir metin dosyasından okundu, bu yüzden std varsayıyorum:
Jack Wilsdon

4
Ne tür bir karakter? char, Unicode kod noktası, genişletilmiş grafik kümesi?
Philipp

Olası yinelenen bir dize yineleme ve ayrıca indeksi (güncel konum) bilebilir nasıl? . indexCevaplardaki kısım için endişelenme .
jww

Yanıtlar:


418
  1. A'nın karakterleri arasında std::stringdöngü tabanlı, döngü tabanlı bir aralık kullanarak (C ++ 11'den, GCC, clang ve VC11 beta'nın son sürümlerinde zaten desteklenmektedir):

    std::string str = ???;
    for(char& c : str) {
        do_things_with(c);
    }
  2. std::stringYineleyiciler ile bir a karakterleri arasında döngü :

    std::string str = ???;
    for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
        do_things_with(*it);
    }
  3. std::stringEski moda bir for döngüsü ile a'nın karakterleri arasında dolaşmak :

    std::string str = ???;
    for(std::string::size_type i = 0; i < str.size(); ++i) {
        do_things_with(str[i]);
    }
  4. Boş sonlandırılmış karakter dizisinin karakterleri arasında geçiş yapmak:

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

4
@Robinson: Bu hatalı bir varsayım. Çok hatalı bir varsayım. Ayrıca, "karakter" çok farklı anlamlara sahiptir, terimden kesinlikle kaçınmak en iyisidir.
Köpek yavrusu

6
@Robinson: "std :: string UTF8 (varsayılan olduğu varsayılır) " Ne zamandan beri ?!
Yörüngedeki Hafiflik Yarışları

2
Peki, Tamam, şimdi (özellikle web üzerinde) utf8 yaygınlığı ve bir boru hattı veya uygulama boyunca tek bir tutarlı kodlama isteyebilir gerçeği göz önüne alındığında, hiçbir kodlama vardır, bu tartışma temelinde benim std :: dizeleri hepsi utf8: s.
Robinson

4
@Robinson: Ve tüm kullanıcıları kodlamasız olarak değerlendiriliyor çünkü ben kullanıcıya bakan bir alanda programlama yapmıyorum (yani insanlara işlenecek herhangi bir dize yok). Karakter kodlamaları hakkında konuşmak istiyorsanız , üstte daha yüksek seviyeli bir soyutlama hakkında konuşmanız gerekir std::string, bu sadece bir bayt dizisidir.
Yörüngedeki Hafiflik Yarışları

1
Ayrıca, vaka 2 ve 3 "otomatik" kullanabileceğiniz / kullanmanız gereken yerlere iyi bir örnektir
galois

29

For for döngüsü şu şekilde uygulanabilir:

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

Bu, karakter dizesini karakter basar. str[i]dizindeki karakteri döndürür i.

Bir karakter dizisiyse:

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

Temelde ikisinin üzerinde c ++ tarafından desteklenen iki tür dizge vardır. İkincisi c string olarak adlandırılır ve ilki std string veya (c ++ string) olarak adlandırılır. C ++ string'i kullanmanızı öneririm, kullanımı çok kolay.


24

Modern C ++ ile:

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

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

C ++ 98 / 03'te:

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

Salt okunur yineleme için, std::string::const_iteratorC ++ 98'de for (char const & c : s)veya yalnızca for (char c : s)C ++ 11'de kullanabilirsiniz.


Kısmi C ++ 11 desteğine sahip derleyiciler için birkaç seçenek: pastebin.com/LBULsn76
Benjamin Lindley

@BenjaminLindley: Teşekkürler! autoher zaman iyi bir fikirdir. Kullanırken begin()ve arasındaki ayrım cbegin()önemli hale gelir.
Kerrek SB

2
burada char içindeki referansın rolü nedir ( char & c)? Sadece gerekli olduğunda karakter değerinin değiştirilmesine izin vermek mi?
LunaticSoul

11

Standart algoritmayı kullanarak bunu yapmanın başka bir yolu.

#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 yılı var, bu yüzden bu doğru cevap olmalı.
rwst

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

4
(Eski yorum, muhtemelen OP için hala önemlidir :) strlenDöngü koşulunda kullanmak için iyi bir form olarak kabul edilmez , çünkü her bir yineleme için dizede O (n) işlemi gerektirir ve tüm döngüyü O (n) yapar. ^ 2) dize boyutunda. strlenDöngü koşulunda, dize döngü sırasında değişirse çağrılabilir, ancak gerçekten gerekli olduğu durumlar için ayrılmalıdır .
Magnus Hoff

@MagnusHoff: Evet, Ressam Schlemiel çirkin kafasını tekrar yetiştiriyor .
Fred Larson

Cevabımı düzenledim. Magnus haklısın, ayy son birkaç yıldır c # 'da foreach kullanıyor;)
demoncodemonkey

Bununla birlikte, her yinelemede null olup olmadığını sınamak yerine, yine de döngü dışında strlen () kullanmalısınız.
mckenzm

4

"C string" ile döngü için bir aralık kullanarak herhangi bir örnek görmüyorum.

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

ilgili değil, int dizi örneği

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

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

1

C-string ( char []) için şöyle bir şey yapmalısınız:

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

İçin std::stringkullanabileceğiniz str.size()örnekteki gibi boyutunu ve iterate almak veya bir yineleyici kullanabilirsiniz:

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

Dize temel olarak bir karakter dizisidir, bu nedenle karakteri almak için dizini belirtebilirsiniz. Dizini bilmiyorsanız, yukarıdaki kod gibi döngü yapabilirsiniz, ancak karşılaştırma yaparken tek tırnak (bir karakter belirtir) kullandığınızdan emin olun.

Bunun dışında, yukarıdaki kod açıklayıcıdır.


-1

Bu şekilde yaptığım gibi, dize kütüphanesinin at işlevini kullanarak bir karakter dizisindeki her karakteri alabilirsiniz

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

bu sadece kodumun bir parçası ama asıl önemli olan karakterlere stringname.at(index)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.