2016-05-21 41 views
2

這樣做的現代方法是什麼?像<cstring>這樣的標題已被棄用,某些編碼風格禁止使用「類C」功能。我有三種做同樣的事情的方法。哪一個會是現代C++最習慣的?將字符串複製到char的現代C++方法*

1.使用迭代器和包括空終止

{ 
    std::string test{"hello, world!"}; 
    char* output = new char[test.size() + 1]; 
    std::copy(test.begin(), test.end(), 
     output); 
    output[test.size() + 1] = '\0'; 
    std::cout << output; 
    delete output; 
} 

2.使用c_str()包括空終止

{ 
    std::string test{"hello, world!"}; 
    char* output = new char[test.size() + 1]; 
    std::copy(test.c_str(), test.c_str() + std::strlen(test.c_str()), 
     output); 
    std::cout << output; 
    delete output; 
} 

3.使用std::strcpy

{ 
    std::string test{"hello, world!"}; 
    char* output = new char[test.size() + 1]; 
    std::strcpy(output, test.c_str()); 
    std::cout << output; 
    delete output; 
} 

我不想看起來像一個面試官說,「哦,你使用strcpy,你必須是一個C程序員」noobot。

+0

如果我是你,我會擔心異常安全性,用'try'包裝整個塊,並抓住'std :: bad_alloc'。另外,「像這樣的標題已被棄用」 - 因爲什麼時候?! –

+1

什麼*確切*是目標數據結構?它是malloc分配的以0結尾的字符串嗎?或者它是「可訪問的0結束字符串」?或者實際上真的是混蛋新分配的0終止的字符串? – Deduplicator

+0

@DanielKamilKozar自C++ 98起。瘋狂,我知道。 – user6364501

回答

10

正確的方法是首先不使用new[]。使用std::vector代替:

std::string temp {"Some string"}; 
std::vector<char> data (begin(temp), end(temp)); 
// If '\0' termination is required: 
data.push_back('\0'); 

您可以訪問他們的背後緩衝datadata.data()。如果你真的由於push_back害怕重新分配,你可以在分配範圍之前有足夠的空間std::vector::reserve

如果您不需要實際可修改的char數組,則可以跳過該副本並直接使用由std::string::datastd::string::c_str返回的指針。

13

現代 安全的前C++ 17獲取連續緩衝區的方法是std::vector

std::string test{"hello, world!"}; 
std::vector<char> output(test.c_str(), test.c_str()+test.size()+1); 
// use output.data() here... 

由於C++ 17,std::string具有非const data()過載。

std::string test{"hello, world!"}; 
char * p = test.data(); 
0

而其他的答案提供了很好的意見,並做的事情幾乎在所有情況下,正確的方法,也有一些真實的情況下,你可能會被迫使用char*而不是容器。最常見的情況是,如果您需要直接與C代碼對接,並且被調用的C方法需要非指針(即它將獲取內存的所有權)。

這是我會怎麼做轉換:

#include <string> 
#include <cstdlib> 

char* convert(const std::string& source) 
{ 
    const auto result = (char*) std::malloc(source.length() + 1); 
    source.copy(result, source.length()); 
    result[source.length()] = '\0'; 
    return result; 
} 

然後你有這樣的:

int main() 
{ 
    const std::string foo {"hello"}; 
    auto p = convert(foo); 
    some_nasty_c_method(p); // promises to free p 
    // other stuff 
} 

作爲一個經驗法則,如果你需要delete自己,不要做這個;改用容器或std::unique_ptr

+0

'std :: vector v(foo.begin(),foo.end()); some_nasty_c_method(v.data());'? –

+0

@ChristianHackl'std :: vector :: data'返回一個'const'指針。 – Daniel

+0

@丹尼爾:[一個重載,但也有一個非常量超載。](http://en.cppreference.com/w/cpp/container/vector/data)然而,這是一個函數,是在給定的指針上調用'free'是獲得通過'malloc'獲得的指針所必需的。這是希望在接口描述中指定的,然後毫無疑問應該使用哪種方法/是最好的,因爲無論如何你必然會使用'malloc'。 – Pixelchemist

相關問題