Std :: string boş sonlandırıcı içeriyor mu?


90

Aşağıdaki dize boş sonlandırıcı '\ 0' içerecek mi?

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

Teşekkürler! :)



1
Şu anda duruyor, @jahhaj'dan kabul edilen cevap, cevabı muhtemelen daha güncel olan user529758'in cevabı ile çelişiyor. İnceleme yaparken Jesse Good'un yorumunu atladım, bu yüzden burada önemini vurgulamak için buradayım.
Jonathan Komar

Yanıtlar:


100

Hayır, ancak temp.c_str()boş bir sonlandırıcı derseniz bu yöntemin getirisine dahil edilecektir.

Diğer herhangi bir karakter gibi bir dizeye boş bir karakter ekleyebileceğinizi de söylemeye değer.

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

baskılar

5 5

ve 5 1boş karakterlerin dizeler için özel bir anlamı varsa beklediğiniz gibi değil .


5
temp.c_str()Boş karakter ararsanız dahil edilecektir. Dizede gerçekten ihtiyacınız varsa, onu diğer herhangi bir karakter gibi ekleyin. temp.push_back('\0'). Şimdi iki boş karakter temp.c_str()içerecek .
jahhaj

1
@dupdupdup, bazı yanıtların da bahsettiği gibi, boş sonlandırılmış bir dizgeye ihtiyacınız varsa, oluşturulan nesnede bir s.c_str () çağırmalısınız. Sonunda '\ 0' olması garantili karakter dizisine bir gösterici döndürecektir.
Maksim Skurydzin

@Rico, Jahhaj O halde string nasıl sonlandırılır. Örneğin - dizime str [i] olarak birkaç karakter ekledim. Şimdi cout kullanarak yazdıramıyorum.
Bhavuk Mathur

Noktanıza eklemek için: << operatörü aşırı yüklendiğinden, cout << s, karakter dizisinin tamamını char ile yazdıracaktır, ancak c_str () alır ve << operatörüne koyarsanız, boş karakter. Aşağıdaki program bu noktayı anlatmaktadır. {string s ("SampleString"); cout << s.size () << "\ t" << s << endl; s [3] = '\ 0'; cout << "\ n \ n Null'dan sonra \ n \ n" << s.size () << "\ t" << s << endl; cout << "\ n \ n c_str alınıyor \ n \ n" << s.size () << "\ t" << s.c_str () << endl; }
Fooo

71

C ++ 03'te değil ve C ++ 11'den önce bile bir C ++ std :: string'in bellekte sürekli olduğu garanti edilmez. Yalnızca C dizeleri (dizeleri depolamak için tasarlanmış char dizileri) boş sonlandırıcıya sahipti.

C ++ 11 ve daha sonra mystring.c_str()eşdeğerdir mystring.data()eşdeğerdir &mystring[0]ve mystring[mystring.size()]olması sağlanır '\0'.


4
C ++ 11 ile dizelerin bellekte bitişik olması artık garanti edilmektedir.
zneak

@zneak teşekkürler! Güncellenmiş. Ancak, en azından makul ölçüde C ++ 11 derleyici olduğundan şüpheliyim ... GCC bile bunun için desteği kırdı.

4
@ H2CO3: kenara C ++ 11, bu ele alındı DR 530 yılında 2005 . Standart kitaplık uygulamalarının büyük çoğunluğu dizi verilerini bitişik bellekte en azından bu kadar uzun süre depolamıştır.
ildjarn

3
Teşekkürler @ildjarn, tam olarak bunu arıyordum. Hareketin gerekçesinin bir kısmı, komitede hiç kimsenin sürekli bellek kullanmayan bir STL uygulamasından haberi olmamasıydı.
zneak

7
@ H2CO3: Dürüst olmak gerekirse, bu sizi rahatsız ettiyse, daha kalın bir cilde ihtiyacınız var.
ildjarn

9

Bu, buradaki "içerme" tanımınıza bağlıdır. İçinde

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

dikkat edilmesi gereken birkaç nokta var:

  • temp.size()İlk gelen karakter sayısını döndürür hson için p(her ikisi de dahil)
  • Ama aynı zamanda temp.c_str()veya temp.data()bir nullsonlandırıcı ile geri dönecek
  • Ya da başka bir deyişle sıfırint(temp[temp.size()]) olacak

Ben burada bazı yanıtlar benzer ses, biliyorum ama işaret etmek istiyorum sizearasında std::stringyer C++almaktadır ayrı tutulan ve benzemese de Csize ilk bulabilirsiniz sürece saymayı tutmak nerede nullterminatör.

Eklemek gerekirse, hikayeniz string literalgömülü içeriyorsa biraz farklı olacaktır \0. Bu durumda, aşağıdaki gibi std::string, ilk nullkarakterdeki durakların oluşturulması :

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

Referanslar:


2

Evet, ararsanız temp.c_str(), boş sonlandırılmış c-string'i döndürecektir.

Bununla birlikte, nesnede depolanan gerçek veriler tempboş sonlandırılmış olmayabilir, ancak önemli değildir ve programcı için önemli olmamalıdır, çünkü o zaman programcı istediğinde const char*, c_str()nesneyi çağırır ve bu da boş değer döndürmesi garantilidir. -sonlu dize.


1
Boş sonlandırıcı (eğer varsa) 'dan dönüşe dahil edilmeyecektir temp.size().
jahhaj

1

C ++ dizeleri ile bunun için endişelenmenize gerek yoktur ve muhtemelen uygulamaya bağlıdır.

Kullanarak temp.c_str()dizenin bir C temsilini elde edersiniz ve bu kesinlikle \0karakteri içerecektir . Bunun dışında, bir C ++ dizesinde nasıl yararlı olacağını gerçekten anlamıyorum


1

std::stringdahili olarak karakter sayısını tutar. Dahili olarak bu sayımı kullanarak çalışır. Diğerlerinin de söylediği gibi, dizgeye gösterim için ihtiyaç duyduğunuzda veya herhangi bir nedenle, c_str()sonunda boş sonlandırıcı olan dizeyi verecek yöntemini kullanabilirsiniz .


Bu ifade için bazı referanslar verebilir misiniz, "std :: string dahili olarak karakterlerin sayısını tutar. Dahili olarak bu sayıyı kullanarak çalışır"
rimalroshan
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.