我正在使用C API,很多函數都帶有字符數組的參數。我聽說使用char
陣列現在被壓低了。但另一方面,使用c_str()
將字符串轉換爲char
陣列似乎是浪費。使用C API時,使用字符數組或使用字符串並根據需要進行轉換?
是否有任何理由以一種方式做到這一點?
我正在使用C API,很多函數都帶有字符數組的參數。我聽說使用char
陣列現在被壓低了。但另一方面,使用c_str()
將字符串轉換爲char
陣列似乎是浪費。使用C API時,使用字符數組或使用字符串並根據需要進行轉換?
是否有任何理由以一種方式做到這一點?
c_str()
調用很可能被內聯 - 它在所需的代碼方面非常小。如果這是唯一讓你退縮的事情,我會使用std::string
。
當然,如果你很擔心,該標準建議適用:
另外要注意,這是一個微型優化;你很可能會浪費開發時間,擔心完全不同於你應該擔心的事情。
std::string
的大多數實現可能會將實際的字符串存儲爲C字符串,因此c_str
函數只是一個內聯函數,它返回一個指針。所以一般來說,我認爲正確的路要走std::string
。
當然,如果字符串是打算由您調用的函數修改,那麼您不能使用std::string
方法。相反,在調用函數之前,必須先將副本複製到自己的緩衝區中,在這種情況下,使用數組可能是一種方法。
如上所述,c_str()
將被內聯。但是沒有提到但我認爲是你的問題最重要的方面之一是std::string
遵循RAII的原則。當使用std::string
時,您不需要記住釋放字符串或需要擔心異常安全。 只要確保std::string
的每個實例都不會被破壞,直到C代碼完成字符串。如果std::string
是由編譯器創建的臨時文件,那麼這尤其可能成爲問題。
如果您的C函數寫回字符串,您可以使用vector<char>
並將大小設置爲所需的緩衝區大小。這樣你仍然會遵循C++ RAII原則。
或者只是使用'std :: string'代替'vector
@MatthieuM。在所有人跳轉並使用std :: string來修改字符串的C函數之前,請記住,您不能使用c_str(),它將返回一個只讀的const char C風格的字符串。所以你必須使用例如&s [0]獲得指向第一個字符的指針。那個記憶是連續的嗎?閱讀http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/ ---矢量始終保證是連續的,但不是字符串。 (當有人問Herb關於字符串的時候,請看下面的註釋) – 2015-04-17 15:37:57
C++ 11改變了規則:** n3485:21.4.1 ** *(5)basic_string對象中類似char的對象應連續存儲。也就是說,對於任何'basic_string'對象's',標識'&*(s.begin()+ n)==&* s.begin()+ n'應該適用於'n'的所有值, '0 <= n
有一個非常簡單的理由使用string
:它的工作原理。
與C字符串工作是一種痛苦:
strlen
,strcpy
和strcat
),因爲該長度不必每次我真的看不到有什麼理由曾經使用C字符串。
許多平臺都提供了自己的特定操作,並提出了許多「更好的字符串」(哦,有多種標準的喜悅),這是一件非常痛苦的事情。
這取決於你在做什麼,以及接口功能 在做什麼。在一個極端,我不認爲有人會建議將字符串文字 轉換爲std::string
,只是這樣你可以在 上調用c_str
它。另一方面:任何動態構建字符串的代碼應該使用 std::string
。像strcpy
和strcat
這樣的函數是 緩衝區溢出的邀請函。兩者之間,這取決於。我認爲標準 應該很容易和安全:只要使用std::string
,使用std::string
即可更容易或更安全地使用 。只要你在做什麼 不需要動態分配char[]
,並且 operator+
等字符串不會被使用,你可以使用char[]
。
如果你很狡猾,仍然可以使用std :: string作爲C++ 11中的緩衝區。 'mystr.resize(BUFFSIZE);'然後'&mystr [0]' – 2012-02-07 16:28:07