Я знаю, что существует множество вопросов о том, как преобразовать std :: string в char *, и благодаря моим исследованиям я принял несколько разных вариантов. Тем не менее, единственное, что мне подходит, это const_cast из метода c_str ().
Поэтому я использую это сейчас, но хотел бы узнать больше информации о том, почему другие методы не работают. Чего мне не хватает в моем понимании того, почему это не работает, как задумано, что, кажется, работает для многих других.
#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();
vector<char> testVec2(testStr.begin(), testStr.end());
это создаст следующий вектор:
vector<char> testVec2 = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd'};
Что-то прыгает на тебя от этого? Должно. Он не содержит нулевой символ-терминатор. Любая попытка использовать testVec2.data()
из-за этого строка C приведет к неопределенному поведению.
Хотя из C++11
std::string
Базовый буфер должен содержать нулевой символ-терминатор, begin - end
Диапазон не включает это.
В C ++ 17 самый простой способ получить char*
из std::string
это просто
std::string str = "Why is this only available since C++17?";
some_c_function(str.data());
Относительно того, почему другие методы не работают, обратитесь к ответ Болова
поскольку c++11
лучший способ получить неконстантная char*
из std::string
это использовать это:
std::string s = "hello";
my_non_const_correct_c_function(&s[0]); // better than using const_cast
С const_cast
вы можете столкнуться с неопределенное поведение если вы используете его на std::string
это не было объявлено const
,