2017-02-27 157 views
2

這與How to convert a vector<char*> to a vector<string>/string問題相反。如何將矢量<string>轉換爲矢量<char*>

我有一些傳統的例程與vector<char*>一起使用,所以我需要改變我的vector<string>

這是我拿出:

std::vector<char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= new char(strVec[i].size()+1); 
    charVec[i][strVec[i].copy(charVec[i], strVec[i].size())] = '\0'; 
} 

這是正確的嗎?

有沒有更好的實現方法?


p.s.當然最後我有:

for (int i=0; i<strVec.size();i++) { 
    delete charVec[i]; 
} 
+0

你的問題是什麼? –

+1

你有問題嗎?看起來像你已經實現了 – vu1p3n0x

+1

它取決於新的向量是否需要擁有它的字符串,或者它只需要臨時查看另一個向量中的字符串。 – Galik

回答

6

這樣做的一個更快的方法是

std::vector<const char*> charVec(strVec.size(),nullptr); 
for (int i=0; i<strVec.size();i++) { 
    charVec[i]= strVec[i].c_str(); 
} 

,然後使用所得到的載體。這將爲大量數據集的內存分配節省大量時間。

+0

你的結果向量必須是'std :: vector '。 'const char *'不能分配給'char *' – MRB

+0

謝謝,我更正了我的答案。我總是忘記c_str返回一個const指針。 – JeremiahB

2

你可以簡單地使用string::c_str()得到串出的std :: string的。更多詳情,請參閱How to convert a std::string to const char* or char*?

或者你可以修改一下函數的主體,但只有你知道這是否值得。


當然作爲ssell提到的意見,請記住,這種方法你不必當你處理它們摧毀你的琴絃!這是一種折衷,你避免了複製(很酷),但是你必須小心不要閱讀垃圾(以防你刪除你的字符串)!

+0

我不會推薦'std :: string :: c_str',因爲它不安全。如果任何他原來的'std :: string'對象被銷燬,'char *'字符串將會失效。像在他的問題中一樣複製數據,其他人在他們的答案中做的更好。請參見[什麼是std :: string :: c_str()生命週期?](http://stackoverflow.com/questions/6456359/what-is-stdstringc-str-lifetime)。 – ssell

+0

@ssell好點,但我不會用「不要觸摸」指令去,我想更多的使用慎用,我會更新! – gsamaras

+1

如果他嚴格控制範圍,那麼你的答案是最直接的。只是想警告潛在的危險。 – ssell

3

你爲什麼要爲你的字符串分配新的緩衝區?您將字符指針的vector傳遞給函數,並最終刪除分配的緩衝區。這意味着這些緩衝區是暫時的,只要源vectorvector<string>)存在,就不需要爲它們分配內存。

您可以輕鬆地做到這一點:

std::vector<std::string> vec1 = { "1", "2", "3" }; 
std::vector<const char*> vec2; 

vec2.resize(vec1.size(), nullptr); 

std::transform(std::begin(vec1), std::end(vec1), std::begin(vec2), [&](const std::string& str) 
{ 
    return str.c_str(); 
}); 
+0

或者你可以用'vec2.reserve()'替換'vec2.resize()',然後使用'std :: back_inserter(vec2)'作爲輸出迭代器。 –

+0

@RemyLebeau當然,好點。我忘記了'std :: back_inserter'。感謝提醒。 – MRB

3

new語句看起來是錯誤的。你想分配一個足夠長的字符串數組。您正在分配一個值爲該字符串長度的單個char。我很驚訝你沒有得到編譯器的警告。

試試這個:

std::vector<char*> charVec; 
for (const auto &str : strVec) { 
    char *charStr = new char[str.size() + 1]; 
    std::strcpy(charStr, str.c_str()); 
    charVec.push_back(charStr); 
} 

唯一的缺點這裏要說的是,如果其中一個字符串中嵌入空字符,沒有超出將被複制。但我懷疑一個函數幾乎可以肯定並不在乎那個。

相關問題