Std :: string có chứa dấu chấm dứt rỗng không?


87

Chuỗi bên dưới có chứa dấu chấm dứt rỗng '\ 0' không?

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

Cảm ơn! :)



1
Hiện tại, câu trả lời được chấp nhận từ @jahhaj xung đột với câu trả lời từ user529758, người có câu trả lời được cho là cập nhật hơn. Trong khi xem xét, tôi đã bỏ qua bình luận của Jesse Good, vì vậy đây là đây để nhấn mạnh tầm quan trọng của nó.
Jonathan Komar

Câu trả lời:


99

Không, nhưng nếu bạn nói temp.c_str()một dấu chấm hết rỗng sẽ được bao gồm trong trả về từ phương thức này.

Cũng cần nói rằng bạn có thể bao gồm một ký tự null trong một chuỗi giống như bất kỳ ký tự nào khác.

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

bản in

5 5

và không 5 1như bạn mong đợi nếu các ký tự null có ý nghĩa đặc biệt đối với chuỗi.


5
Nếu bạn gọi temp.c_str()ký tự null sẽ được bao gồm. Nếu bạn thực sự cần nó trong chuỗi, chỉ cần thêm nó giống như bất kỳ ký tự nào khác. temp.push_back('\0'). Bây giờ temp.c_str()sẽ bao gồm hai ký tự rỗng.
jahhaj

1
@dupdupdup, như một số câu trả lời đã đề cập, nếu bạn cần một chuỗi kết thúc bằng null, bạn nên gọi một s.c_str () trên đối tượng được xây dựng. Nó sẽ trả về một con trỏ tới mảng ký tự được đảm bảo có '\ 0' ở cuối.
Maksim Skurydzin

@Rico, Jahhaj Làm thế nào để kết thúc chuỗi sau đó. Ví dụ - tôi đã thêm một vài ký tự vào chuỗi của mình dưới dạng str [i]. Bây giờ tôi không thể in nó bằng cout.
Bhavuk Mathur

Để bổ sung cho quan điểm của bạn: Vì toán tử << bị quá tải nên cout << s, mặc dù sẽ in chuỗi ký tự hoàn chỉnh bởi ký tự char, nhưng nếu bạn lấy c_str () và đặt vào toán tử << thì nó sẽ in cho đến khi ký tự rỗng. chương trình sau đây loại bỏ điểm này. {string s ("SampleString"); cout << s.size () << "\ t" << s << endl; s [3] = '\ 0'; cout << "\ n \ n Sau khi Null \ n \ n" << s.size () << "\ t" << s << endl; cout << "\ n \ n Lấy c_str \ n \ n" << s.size () << "\ t" << s.c_str () << endl; }
Fooo

70

Không có trong C ++ 03 và thậm chí không được đảm bảo trước C ++ 11 rằng trong C ++ std :: chuỗi là liên tục trong bộ nhớ. Chỉ có chuỗi C (mảng ký tự được dùng để lưu trữ chuỗi) có dấu chấm hết là null.

Trong C ++ 11 trở lên, mystring.c_str()tương đương với mystring.data()tương đương với &mystring[0]mystring[mystring.size()]được đảm bảo là như vậy '\0'.


4
Với C ++ 11, các chuỗi bây giờ được đảm bảo liền kề trong bộ nhớ.
zneak

@zneak cảm ơn! Đã cập nhật. Nhưng tôi nghi ngờ có bất kỳ trình biên dịch nào ít nhất là hợp lý C ++ 11 ... ngay cả GCC đã không hỗ trợ cho nó.

4
@ H2CO3: C ++ 11 sang một bên, điều này đã được giải quyết trong DR 530 vào năm 2005 . Phần lớn các triển khai thư viện tiêu chuẩn đã lưu trữ dữ liệu chuỗi trong bộ nhớ liền kề ít nhất là lâu.
ildjarn

3
Cảm ơn bạn @ildjarn, tôi đã tìm kiếm chính xác. Một phần lý do của động thái này là không ai trong ủy ban biết về việc triển khai STL không sử dụng bộ nhớ liên tục.
zneak

7
@ H2CO3: Thành thật mà nói, nếu điều đó xúc phạm bạn, bạn cần có làn da dày hơn.
ildjarn

8

Điều này phụ thuộc vào định nghĩa của bạn về 'chứa' ở đây. Trong

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

có một số điều cần lưu ý:

  • temp.size()sẽ trả về số ký tự từ đầu tiên hđến cuối cùng p(bao gồm cả hai)
  • Nhưng đồng thời temp.c_str()hoặc temp.data()sẽ trở lại với một dấu nullchấm hết
  • Hay nói cách khác int(temp[temp.size()])sẽ là số không

Tôi biết, tôi âm thanh tương tự như một số các câu trả lời ở đây nhưng tôi muốn chỉ ra rằng sizecác std::stringtại C++được duy trì một cách riêng biệt và nó không phải là như trong Cnơi bạn giữ đếm trừ khi bạn tìm ra đầu tiên nullterminator.

Nói thêm, câu chuyện sẽ khác một chút nếu nội dung của bạn string literalđược nhúng \0. Trong trường hợp này, việc xây dựng các std::stringđiểm dừng ở nullký tự đầu tiên , như sau:

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

Người giới thiệu:


2

Có nếu bạn gọi temp.c_str(), thì nó sẽ trả về chuỗi c-kết thúc bằng null.

Tuy nhiên, dữ liệu thực tế được lưu trữ trong đối tượng tempcó thể không bị kết thúc bằng null, nhưng điều đó không quan trọng và không quan trọng đối với lập trình viên, bởi vì khi lập trình viên muốn const char*, anh ta sẽ gọi c_str()đối tượng, được đảm bảo trả về null -mã kết thúc.


1
Cũng không bao gồm dấu chấm dứt null (nếu nó tồn tại) trong trả về từ temp.size().
jahhaj

1

Với chuỗi C ++, bạn không phải lo lắng về điều đó và nó có thể phụ thuộc vào việc triển khai.

Khi sử dụng, temp.c_str()bạn sẽ có được một biểu diễn C của chuỗi, chắc chắn sẽ chứa ký tự \0char. Ngoài ra, tôi không thực sự thấy nó sẽ hữu ích như thế nào trên một chuỗi C ++


1

std::stringbên trong giữ một số lượng ký tự. Nội bộ nó hoạt động bằng cách sử dụng số lượng này. Giống như những người khác đã nói, khi bạn cần chuỗi để hiển thị hoặc bất cứ lý do gì, bạn có thể thực hiện c_str()phương thức của nó để cung cấp cho bạn chuỗi với dấu chấm dứt null ở cuối.


Bạn có thể đưa ra một số tài liệu tham khảo cho tuyên bố này, "std :: string trong nội bộ giữ một đếm số ký tự nội nó hoạt động sử dụng số này."
rimalroshan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.