将std字符串转换为char *的方法的不同之处

时间:2017-11-16 14:38:05

标签: c++ stdvector c++17 stdstring visual-c++-2017

我知道如何将std :: string转换为char *有很多问题,通过我的研究,我采用了一些不同的选项。然而,似乎对我有用的唯一一个是来自c_str()方法的const_cast。

所以我现在正在使用它,但想了解更多关于为什么其他方法不起作用的信息。在我理解为什么这个没有按预期工作的情况下我缺少什么,似乎对许多其他人有效。

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    char* test = "Hello World";
    string testStr(test);

    vector<char> testVec2(testStr.begin(), testStr.end());
    // testVec2[0] = 'F';
    char* test2 = reinterpret_cast<char*>(testVec2.data());

    vector<char> testVec3(testStr.begin(), testStr.end());
    // testVec3[0] = 'G'; 
    char* test3 = &testVec3[0];

    // The only one that works
    char* test4 = const_cast<char*>(testStr.c_str());

    cout << "char* test: " << test << " [" << strlen(test) << "]" << endl;
    cout << "str test: " << testStr << " [" << testStr.length() << "]" <<     endl;
    cout << "=== conv testing === " << endl;
    cout << "char* test2: " << test2 << " [" << strlen(test2) << "]" <<     endl;
    cout << "char* test3: " << test3 << " [" << strlen(test3) << "]" << endl;
    cout << "char* test4: " << test4 << " [" << strlen(test4) << "]" << endl;

    cin.get();
    return 0;
}

我知道使用const_cast的缺陷但它现在适用于我的情况。我只是从用户那里获取字符串,将其传递给C API并且不做任何其他事情(不用担心它被修改)。

以下是输出示例 https://imgur.com/a/2S1HD

那么我做错了什么,是否有更好的方法来做到这一点?

更新 感谢大家的极快答案。似乎我的潜在混淆是假设空终止字符不在我分配给char *变量的新缓冲区中。因此,为什么我的输出显示字符串后面的随机字符(应该是我的线索,但它已经很长时间以来我已经完成了C / C ++)

我也应该最初标记这个C ++ 17(自修复以来),因为这就是我的目标。我没有在Visual Studio中的控制台应用程序中启用它,而Passer通过以下工作制作了解决方案。这是我将继续使用的方法。

底线,将我的目标更改为C ++ 17这可以按预期工作

char* test = "Hello World";
string testStr(test);
vector<char> testVec2(testStr.begin(), testStr.end());  
char* test2 = testStr.data();

3 个答案:

答案 0 :(得分:4)

vector<char> testVec2(testStr.begin(), testStr.end());

这将创建以下向量:

vector<char> testVec2 = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};

有什么东西从你那里跳过来?这应该。它不包含null终止符。因此,任何将testVec2.data()用作C字符串的尝试都将导致未定义的行为。

虽然从C++11 std::string的底层缓冲区必须包含空终止符,但begin - end范围不包含它。

答案 1 :(得分:3)

在C ++ 17中,从char*获取std::string的最简单方法就是

std::string str = "Why is this only available since C++17?";
some_c_function(str.data());

至于为什么其他方法不起作用,请参阅bolov's answer

答案 2 :(得分:1)

c++11开始,从char*获取非const std::string的最佳方法是使用此功能:

std::string s = "hello";

my_non_const_correct_c_function(&s[0]); // better than using const_cast

如果您在未声明为const_cast的{​​{1}}上使用<{1}},则可以遇到未定义的行为