-1

我知道关于如何将 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 By 下面的解决方案起作用。这就是我今后将使用的方法。

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

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

3 回答 3

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

这将创建以下向量:

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

有什么让你兴奋的吗?它应该。它不包含空终止符。因此,任何用作 C 字符串的尝试testVec2.data()都将导致未定义的行为。

尽管 fromC++11 std::string的底层缓冲区必须包含空终止符,但该begin - end范围不包括它。

于 2017-11-16T14:45:23.957 回答
3

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

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

至于为什么其他方法不起作用,参考bolov的回答

于 2017-11-16T14:54:47.163 回答
1

由于从 a获取非常量c++11的最佳方法是使用以下方法: char*std::string

std::string s = "hello";

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

如果您在未声明的 a 上使用它,const_cast您可能会遇到未定义的行为std::stringconst

于 2017-11-16T14:48:15.887 回答