2013-08-28 135 views
1

目前我有一個複雜的函數,我和我們的團隊不想重構利用std :: string,它需要一個被修改的char *。我將如何正確地將一個字符串:: c_str()的深層副本轉換爲char *?我是而不是尋找修改字符串的內部存儲的char *。深拷貝std :: string :: c_str()char *

char *cstr = string.c_str(); 

失敗,因爲c_str()const的是。

+4

這是C++ 11嗎?複製'std :: string'並使用'&stringCopy [0]'。 – chris

+1

'strdup','new/strcpy',@chris'建議,...您有選擇。 – syam

+0

sprintf(cstr,「%s」,somestring.c_str()) – bartimar

回答

6

你可以這樣說:

const std::string::size_type size = string.size(); 
char *buffer = new char[size + 1]; //we need extra char for NUL 
memcpy(buffer, string.c_str(), size + 1); 
+6

*請使用正確類型的字符串大小,例如。 'std :: string :: size_type'或'std :: size_t'。 – syam

+0

@syam ahh你絕對正確:) –

+1

不要忘記刪除它。或者更好的是,讓'std :: vector '爲你做,並且以'v.data()'或'&v [0]'的形式訪問數組。或者甚至是另一個'string',如果你不介意邊界未定義的行爲。 –

4

而不是修改現有的功能,我只希望創建作爲一個包裝過載。假設現有的功能是ret_type f(char *),我會寫過載類似:

ret_type f(std::string s) { 
    return f(&s[0]); 
} 

說明值而不是引用傳遞s,減少消耗,以獲得字符串的副本的努力。

理論上,直到C++ 03之前,這並不保證能夠正常工作(即字符串的緩衝區不保證是連續的)。實際上,委員會的這一擔保相當容易,主要是因爲沒有人知道std::string的執行情況。

同樣,理論上它可能會丟失NUL終止符。如果你擔心這種可能性,你可以使用return f(const_cast<char *>(s.c_str()));代替,或者返回前添加一個s.push_back('\0');

ret_type f(std::string s) { 
    s.push_back('\0'); 
    return f(&s[0]); 
} 
+0

我會在你的包裝函數中做's.push_back('\ 0')',這是可以肯定的。而且你肯定是在最後一段代碼中使用'const_cast'。 –

+0

@JamesKanze:哎呀 - 是的,當然。 –

1

顯而易見的解決方案是:

std::vector<char> tmp(string.begin(), string.end()); 
tmp.push_back('\0'); 
function(&tmp[0]); 

(我比較喜歡傑裏棺材的解決方案,但是)