std :: string มี null terminator หรือไม่


90

สตริงด้านล่างจะมีเครื่องหมาย null '\ 0' หรือไม่

std::string temp = "hello whats up";

ขอบคุณ! :)



1
ในตอนนี้คำตอบที่ได้รับการยอมรับจาก @jahhaj ขัดแย้งกับคำตอบจาก user529758 ซึ่งคำตอบนั้นมีเนื้อหาที่ทันสมัยกว่า ในขณะที่อ่านฉันข้ามความคิดเห็นของเจสซีกู๊ดดังนั้นนี่จึงเป็นการเน้นย้ำถึงความสำคัญ
Jonathan Komar

คำตอบ:


100

ไม่ แต่ถ้าคุณบอกว่าเทอร์มิเนเตอร์temp.c_str()ว่างจะรวมอยู่ในผลตอบแทนจากวิธีนี้

นอกจากนี้ยังควรค่าแก่การบอกว่าคุณสามารถใส่อักขระว่างในสตริงได้เช่นเดียวกับอักขระอื่น ๆ

string s("hello");
cout << s.size() << ' ';
s[1] = '\0';
cout << s.size() << '\n';

พิมพ์

5 5

และไม่ใช่5 1อย่างที่คุณคาดหวังหากอักขระ null มีความหมายพิเศษสำหรับสตริง


5
หากคุณเรียกtemp.c_str()ใช้อักขระ null จะรวมอยู่ด้วย หากคุณต้องการจริงๆในสตริงให้เพิ่มเหมือนอักขระอื่น ๆ temp.push_back('\0'). ตอนนี้temp.c_str()จะรวมอักขระว่างสองตัว
jahhaj

1
@dupdupdup ดังที่คำตอบบางส่วนได้กล่าวไว้หากคุณต้องการสตริงที่สิ้นสุดด้วยค่าว่างคุณควรเรียกใช้ s.c_str () บนวัตถุที่สร้างขึ้น มันจะส่งกลับตัวชี้ไปยังอาร์เรย์อักขระที่รับประกันว่าจะมี '\ 0' ต่อท้าย
Maksim Skurydzin

@Rico, Jahhaj จะยุติสตริงได้อย่างไร เช่น - ฉันเพิ่มอักขระสองสามตัวในสตริงของฉันเป็น str [i] ตอนนี้ยังพิมพ์โดยใช้ cout ไม่ได้
Bhavuk Mathur

เพื่อเพิ่มไปยังจุดของคุณ: เนื่องจากตัวดำเนินการ << มีงานมากเกินไปดังนั้น cout << s แม้ว่าจะพิมพ์อักขระสตริงที่สมบูรณ์โดย char แต่ถ้าคุณใช้ c_str () และนำไปที่ตัวดำเนินการ << มันจะพิมพ์จนถึง null ถ่าน โปรแกรมต่อไปนี้แสดงถึงประเด็นนี้ {สตริง s ("SampleString"); cout << s.size () << "\ t" << s << endl; s [3] = '\ 0'; cout << "\ n \ n หลัง Null \ n \ n" << s.size () << "\ t" << s << endl; cout << "\ n \ n การ c_str \ n \ n" << s.size () << "\ t" << s.c_str () << endl; }
Fooo

71

ไม่ได้อยู่ใน C ++ 03 และไม่มีการรับประกันก่อน C ++ 11 ว่าในสตริง C ++ std :: นั้นต่อเนื่องในหน่วยความจำ เฉพาะสตริง C (อาร์เรย์ถ่านที่มีไว้สำหรับจัดเก็บสตริง) เท่านั้นที่มีตัวยุติเป็นโมฆะ

ใน C ++ 11 และหลังจากนั้นmystring.c_str()จะเทียบเท่ากับmystring.data()เทียบเท่ากับ&mystring[0]และรับประกันได้ว่าจะmystring[mystring.size()]'\0'


4
ด้วย C ++ 11 ตอนนี้สตริงได้รับการรับรองว่าอยู่ติดกันในหน่วยความจำ
zneak

@zneak ขอบคุณ! อัปเดตแล้ว แต่ฉันสงสัยว่ามีคอมไพเลอร์คอมไพเลอร์ C ++ 11 อย่างสมเหตุสมผล ... แม้แต่ GCC ก็ยังไม่รองรับมัน

4
@ H2CO3: C ++ 11 กันนี้ได้รับการแก้ไขในDR 530ใน2005 การใช้งานไลบรารีมาตรฐานส่วนใหญ่ได้จัดเก็บข้อมูลสตริงไว้ในหน่วยความจำที่ต่อเนื่องกันเป็นเวลานานอย่างน้อยที่สุด
ildjarn

3
ขอบคุณ @ildjarn ฉันกำลังมองหาสิ่งนั้นอยู่ เหตุผลส่วนหนึ่งของการย้ายคือไม่มีใครในคณะกรรมการทราบถึงการนำ STL ที่ไม่ใช้หน่วยความจำต่อเนื่อง
zneak

7
@ H2CO3: พูดตามตรงถ้ามันทำให้คุณขุ่นเคืองคุณต้องมีผิวที่หนาขึ้น
ildjarn

9

ขึ้นอยู่กับคำจำกัดความของ "มี" ที่นี่ ใน

std::string temp = "hello whats up";

มีบางสิ่งที่ควรทราบ:

  • temp.size()จะส่งคืนจำนวนอักขระจากตัวแรกhถึงตัวสุดท้ายp(รวมทั้งคู่)
  • แต่ในเวลาเดียวกันtemp.c_str()หรือtemp.data()จะกลับมาพร้อมกับเทอร์nullมิเนเตอร์
  • หรืออีกนัยหนึ่งint(temp[temp.size()])จะเป็นศูนย์

ฉันรู้ว่าฉันเสียงคล้ายกับบางส่วนของคำตอบที่นี่ แต่ผมอยากจะชี้ให้เห็นว่าsizeของstd::stringในC++จะถูกเก็บรักษาไว้ที่แยกจากกันและมันก็ไม่เหมือนในCที่คุณเก็บนับจนกว่าคุณจะพบคนแรกที่nullเทอร์มิ

หากต้องการเพิ่มเรื่องราวจะแตกต่างกันเล็กน้อยหากstring literalมีการฝังของ\0คุณ ในกรณีนี้การสร้างstd::stringจุดหยุดที่nullอักขระตัวแรกดังต่อไปนี้:

std::string s1 = "ab\0\0cd";   // s1 contains "ab",       using string literal
std::string s2{"ab\0\0cd", 6}; // s2 contains "ab\0\0cd", using different ctr
std::string s3 = "ab\0\0cd"s;  // s3 contains "ab\0\0cd", using ""s operator

อ้างอิง:


2

ใช่ถ้าคุณโทรtemp.c_str()มันจะส่งคืน c-string ที่สิ้นสุดด้วย null

อย่างไรก็ตามข้อมูลจริงที่จัดเก็บในออบเจ็กต์tempอาจไม่ถูกยกเลิกด้วยค่าว่าง แต่ก็ไม่สำคัญและไม่ควรมีความสำคัญกับโปรแกรมเมอร์เพราะเมื่อนั้นโปรแกรมเมอร์ต้องการconst char*เขาจะเรียกc_str()ใช้วัตถุซึ่งรับประกันว่าจะคืนค่าว่าง -terminated สตริง


1
หรือจะฮือ null (ถ้ามี) temp.size()จะรวมอยู่ในผลตอบแทนจาก
jahhaj

1

ด้วยสตริง C ++ คุณไม่ต้องกังวลเกี่ยวกับเรื่องนี้และอาจขึ้นอยู่กับการนำไปใช้งาน

การใช้temp.c_str()คุณจะได้รับ C แทนสตริงซึ่งจะมี\0อักขระอยู่แน่นอน นอกเหนือจากนั้นฉันไม่เห็นว่ามันจะมีประโยชน์กับสตริง C ++ อย่างไร


1

std::stringเก็บจำนวนอักขระไว้ภายใน ภายในใช้งานได้โดยใช้การนับนี้ เช่นเดียวกับคนอื่น ๆ ได้กล่าวไว้เมื่อคุณต้องการสตริงสำหรับการแสดงผลหรือเหตุผลใดก็ตามคุณสามารถc_str()ใช้วิธีการซึ่งจะให้สตริงที่มีตัวยุติเป็นโมฆะในตอนท้าย


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