簡體   English   中英

將'\\ 0'添加到std :: string時出現意外行為

[英]Unexpected behavior on adding '\0' to std::string

為什么C ++標准允許以下內容?

#include <iostream>
#include <string>    

int main()
{
    std::string s(10, '\0'); // s.length() now is 10
    std::cout << "string is " << s << ", length is " << s.length() << std::endl;
    s.append(5, '\0'); // s.length() now is 15 
    std::cout << "string is " << s << ", length is " << s.length() << std::endl;
    // the same with += char and push_back 

    // but:
    s += "hello"; // s.length() returns 20 string is "hello"
    std::cout << "string is " << s << ", length is " << s.length() << std::endl;

    return 0;
}

為什么它會加0並計算它? 它看起來像字符串的完整性,不是嗎? 但我檢查標准,這是正確的行為。

為什么標准允許遵循?

因為設計C ++字符串的人決定應該允許這樣的事情。 我不確定那些設計C ++字符串的團隊是否屬於某個人......但是既然你自己說標准允許它,那就是它的樣子,我懷疑它是否會改變。

擁有一個可以包含“任何東西”的字符串有時候很實用。 當我不得不解決C樣式字符串不能包含零字節的事實時,我可以想到一些實例。 除了長C風格的字符串需要很長時間才能找到它的長度之外,C ++字符串的主要好處是它們不僅限於“你可以放入它們的內容” - 這在我的書中是件好事。

不知道這里有什么問題。

std::string中間添加'\\0'不會改變任何內容 - null字符被視為任何其他字符。 唯一可以改變的是,如果你使用.c_str()函數接受以null結尾的字符串。 但是,這不是.c_str()問題,只有特殊處理'\\0'的函數。

如果您想知道這個字符串有多少字符就好像處理以null結尾的字符串一樣,請使用

size_t len = strlen(s.c_str());

注意它是O(n)操作,因為這是strlen工作原理。

如果你問為什么+=運算符沒有將字符串文字"hello"的隱式空字符添加到字符串中,我說反向(添加它)不清楚,絕對不是你想要99%的時間。 另一方面,如果要在字符串中添加'\\0' ,只需將其作為緩沖區附加:

char buffer[] = "Hello";
s.append(buffer, sizeof(buffer));

或者(甚至更好)完全刪除char數組和以null結尾的字符串,並使用C ++樣式替換,如std::string作為NTS替換, std::vector<char>作為連續緩沖區, std::vector作為動態數組指針替換,以及std::array (C ++ 11)作為標准C數組替換。

另外,(如評論中的@AdamRosenfield所述),添加"hello"后的字符串實際上有20個字符,可能只是你的終端不打印空值。

NUL char '\\0'c style string的結束字符,而不是std::string s。 但是,它支持此字符從const char指針獲取值,以便它可以找到c樣式字符串的結尾。 否則,它會像其他角色一樣對待

std :: string更像是一個容器,而不是其他任何東西,\\ 0是一個字符。 作為一個真實的例子,請看一下Windows中的CreateProcess函數。 lpEnvironment參數采用以null結尾的以空字符結尾的字符串塊(即A=1\\0B=2\\0C=3\\0\\0 )。 如果你正在構建一個塊,那么使用std :: string很方便。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM