สำหรับอักขระทุกตัวในสตริง


229

ฉันจะทำ for loop กับตัวละครทุกตัวใน string ใน C ++ ได้อย่างไร


9
สตริงประเภทใด C-string หรือstd::string?
Mysticial

อ่านจากไฟล์ข้อความดังนั้นฉันสมมุติว่า std ::
Jack Wilsdon

4
บุคลิกแบบไหน char, จุดโค้ด Unicode, คลัสเตอร์กราฟที่ขยายเพิ่มเติม?
ฟิลิปป์

เป็นไปได้ที่ซ้ำกันของฉันจะทำซ้ำผ่านสตริงและรู้ดัชนี (ตำแหน่งปัจจุบัน) ได้อย่างไร . ไม่ต้องกังวลเกี่ยวกับindexคำตอบ
jww

คำตอบ:


417
  1. วนลูปผ่านตัวอักษรของ a std::stringโดยใช้ช่วงสำหรับลูป (มาจาก C ++ 11 ได้รับการสนับสนุนใน GCC, clang และ VC11 เบต้าล่าสุดแล้ว:

    std::string str = ???;
    for(char& c : str) {
        do_things_with(c);
    }
    
  2. วนลูปผ่านตัวอักษรของ a std::stringด้วยตัววนซ้ำ:

    std::string str = ???;
    for(std::string::iterator it = str.begin(); it != str.end(); ++it) {
        do_things_with(*it);
    }
    
  3. วนลูปผ่านตัวอักษรของ a std::stringพร้อมกับวนลูปแบบเก่า:

    std::string str = ???;
    for(std::string::size_type i = 0; i < str.size(); ++i) {
        do_things_with(str[i]);
    }
    
  4. วนลูปผ่านตัวอักขระของอาร์เรย์อักขระที่สิ้นสุดด้วยค่า null:

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

4
@ Robinson: นั่นเป็นข้อสันนิษฐานที่ผิดพลาด สมมติฐานที่ผิดพลาดมาก นอกจากนี้ "ตัวละคร" ก็มีความหมายที่แตกต่างกันมากมายดังนั้นควรหลีกเลี่ยงคำนี้อย่างเคร่งครัด
ลูกสุนัข

6
@ Robins: "std :: string คือ UTF8 (สันนิษฐานว่าเป็น) " ตั้งแต่เมื่อไหร่?!
Lightness Races ในวงโคจร

2
โอเคไม่มีการเข้ารหัส แต่ได้รับความแพร่หลายของ utf8 ในขณะนี้ (โดยเฉพาะอย่างยิ่งบนเว็บ) และความจริงที่ว่าเราอาจต้องการการเข้ารหัสที่สอดคล้องกันเพียงครั้งเดียวตลอดทั้งท่อหรือแอปพลิเคชันสำหรับพื้นฐานของการสนทนานี้ ทั้งหมดคือ utf8: p
Robinson

4
@Robinson: และทั้งหมดของฉันจะถือว่าเป็นการเข้ารหัสน้อยเพราะฉันไม่ได้เขียนโปรแกรมในโดเมนที่ผู้ใช้หันหน้าไปทาง (นั่นคือไม่มีสตริงที่กำหนดให้มนุษย์) หากคุณต้องการพูดคุยเกี่ยวกับการเข้ารหัสตัวอักษรคุณต้องพูดถึงสิ่งที่เป็นนามธรรมใน ระดับที่สูงกว่าstd::stringซึ่งเป็นเพียงจำนวนไบต์
การแข่งขัน Lightness ในวงโคจร

1
นอกจากนี้กรณีที่ 2 และ 3 เป็นตัวอย่างที่ดีที่คุณสามารถ / ควรใช้ "auto"
galois

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
Benjamin Lindley

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

เรามีปี 2561 ดังนั้นนี่ควรเป็นคำตอบที่ถูกต้อง
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: ใช่Schlemiel the Painterกลับมาเป็นหัวหน้าที่น่าเกลียดอีกครั้ง
Fred Larson

ฉันแก้ไขคำตอบของฉันแล้ว แมกนัสคุณพูดถูก oops ใช้ foreach ใน c # ในช่วงสองสามปีที่ผ่านมา;)
demoncodemonkey

อย่างไรก็ตามคุณควรใช้ strlen () นอกลูปเพื่อทำการทดสอบค่าว่างในการวนซ้ำทุกครั้ง
mckenzm

4

ฉันไม่เห็นตัวอย่างใด ๆ โดยใช้ช่วงสำหรับลูปด้วย "c string"

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

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)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.