Apakah std :: string berisi terminator null?

90

Akankah string di bawah ini berisi terminator nol '\ 0'?

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

Terima kasih! :)

tuan
sumber
1
Saat ini, jawaban yang diterima dari @jahhaj bertentangan dengan jawaban dari pengguna529758, yang jawabannya bisa dibilang lebih terkini. Saat membaca dengan teliti, saya melewatkan komentar Jesse Good, jadi ini di sini untuk menekankan pentingnya komentar tersebut.
Jonathan Komar

Jawaban:

100

Tidak, tetapi jika Anda mengatakan temp.c_str()terminator null akan dimasukkan dalam pengembalian dari metode ini.

Perlu juga dikatakan bahwa Anda dapat menyertakan karakter nol dalam string seperti karakter lainnya.

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

cetakan

5 5

dan tidak 5 1seperti yang Anda harapkan jika karakter nol memiliki arti khusus untuk string.

jahhaj
sumber
5
Jika Anda memanggil temp.c_str()karakter null akan dimasukkan. Jika Anda benar-benar membutuhkannya dalam string, tambahkan saja seperti karakter lainnya. temp.push_back('\0'). Sekarang temp.c_str()akan menyertakan dua karakter nol.
jahhaj
1
@dupdupdup, seperti yang disebutkan beberapa balasan, jika Anda memerlukan string yang diakhiri dengan null, Anda harus memanggil s.c_str () pada objek yang dibuat. Ini akan mengembalikan pointer ke array karakter yang dijamin memiliki '\ 0' di bagian akhir.
Maksim Skurydzin
@Rico, Jahhaj Bagaimana cara mengakhiri string itu. Misalnya - Saya menambahkan beberapa karakter ke string saya sebagai str [i]. Sekarang saya tidak bisa mencetaknya menggunakan cout.
Bhavuk Mathur
Untuk menambah poin Anda: Karena operator << kelebihan beban jadi, cout << s, meskipun akan mencetak string lengkap char demi char, tetapi, jika Anda mengambil c_str () dan meletakkan ke operator << itu akan mencetak sampai null char. Program berikut menjelaskan hal ini. {string s ("SampleString"); cout << s.size () << "\ t" << s << endl; s [3] = '\ 0'; cout << "\ n \ n Setelah Null \ n \ n" << s.size () << "\ t" << s << endl; cout << "\ n \ n Mengambil c_str \ n \ n" << s.size () << "\ t" << s.c_str () << endl; }
Fooo
71

Tidak dalam C ++ 03, dan bahkan tidak dijamin sebelum C ++ 11 bahwa dalam C ++ std :: string kontinu dalam memori. Hanya string C (array karakter yang dimaksudkan untuk menyimpan string) yang memiliki terminator null.

Di C ++ 11 dan yang lebih baru, mystring.c_str()ekuivalen dengan mystring.data()ekuivalen dengan &mystring[0], dan mystring[mystring.size()]dijamin akan menjadi '\0'.

Quuxplusone
sumber
4
Dengan C ++ 11, string sekarang dijamin bersebelahan dalam memori.
zneak
@zneak terima kasih! Diperbarui. Tapi saya ragu setidaknya ada kompiler C ++ 11-compilant ... bahkan GCC telah merusak dukungan untuk itu.
4
@ H2CO3: Selain C ++ 11, ini telah diatasi di DR 530 pada tahun 2005 . Sebagian besar implementasi pustaka standar telah menyimpan data string dalam memori yang berdekatan setidaknya selama itu.
ildjarn
3
Terima kasih @ildjarn, saya mencari itu persis. Bagian dari alasan untuk pindah adalah bahwa tidak ada seorang pun di komite yang mengetahui implementasi STL yang tidak menggunakan memori terus menerus.
zneak
7
@ H2CO3: Jujur saja, jika itu menyinggung Anda, Anda membutuhkan kulit yang lebih tebal.
ildjarn
9

Ini tergantung pada definisi Anda tentang 'berisi' di sini. Di

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

ada beberapa hal yang perlu diperhatikan:

  • temp.size()akan mengembalikan jumlah karakter dari awal hhingga akhirp (keduanya inklusif)
  • Tetapi pada saat yang sama temp.c_str()atau temp.data()akan kembali dengan anull terminator
  • Atau dengan kata lain int(temp[temp.size()])akan menjadi nol

Aku tahu, aku terdengar mirip dengan beberapa jawaban di sini tapi aku ingin menunjukkan bahwa sizedari std::stringdalam C++adalah secara terpisah dan tidak seperti di Cmana Anda menyimpan penghitungan kecuali jika Anda menemukan pertamanull terminator.

Sebagai tambahan, ceritanya akan sedikit berbeda jika konten Anda string literaldisematkan \0. Dalam hal ini, pembangunan std::stringberhenti pada nullkarakter pertama , sebagai berikut:

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

Referensi:

aniliitb10.dll
sumber
2

Ya jika Anda menelepon temp.c_str() , maka itu akan mengembalikan c-string yang diakhiri null.

Namun, data aktual yang disimpan dalam objek tempmungkin tidak null-terminated, tetapi itu tidak masalah dan seharusnya tidak masalah bagi programmer, karena ketika programmer menginginkannya const char*, dia akan memanggil c_str()objek tersebut, yang dijamin akan mengembalikan null string -terminated.

Nawaz
sumber
1
Juga tidak akan terminator nol (jika ada) dimasukkan dalam pengembalian dari temp.size().
jahhaj
1

Dengan string C ++ Anda tidak perlu khawatir tentang itu, dan ini mungkin bergantung pada implementasinya.

Menggunakan temp.c_str()Anda mendapatkan representasi C dari string, yang pasti akan berisi \0karakter. Selain itu, saya tidak benar-benar melihat bagaimana itu akan berguna pada string C ++

Tidur siang 62
sumber
1

std::stringsecara internal menghitung jumlah karakter. Secara internal, ini berfungsi menggunakan hitungan ini. Seperti yang dikatakan orang lain, ketika Anda membutuhkan string untuk tampilan atau alasan apa pun, Anda dapat c_str()metode yang akan memberi Anda string dengan terminator nol di bagian akhir.

Superman
sumber
Dapatkah Anda memberikan beberapa referensi untuk pernyataan ini, "std :: string secara internal menyimpan hitungan jumlah karakter. Secara internal bekerja menggunakan hitungan ini"
rimalroshan