Как мне преобразовать вектор<string> в const char* const* в C++?
Я пытаюсь преобразовать данные в правильный формат для конкретного модульного теста. Задача состоит в том, чтобы подобрать набор слов, модульные тесты убедятся, что результаты верны. У меня нет доступа к модульным тестам, только объявление, которое принимает const char* const* Result.
Так что мне нужно, чтобы мой
std::vector<string> Words;
в
const char* const* Result;
делится на не альфа-символ (например, пробел).
Я знаю, что это постоянный указатель на постоянный символ, поэтому я не уверен, что здесь делать, так как они оба постоянны?
Любые указатели (слово каламбур на самом деле не предназначен) приветствуются!
3 ответа
Вы не можете осмысленно преобразовать одно в другое. Тем не менее, вы можете преобразовать массив std::string
в массив указателей на char, и указатель на первый элемент такого массива будет совместим с желаемым результатом:
std::vector<const char*> Ptrs;
std::transform(
std::cbegin(Words), std::cend(Words),
std::back_inserter(Ptrs),
[](auto& str) { return str.c_str(); }
);
const char* const* Result = Ptrs.data();
Просто помните, что сами строки все еще хранятся в std::string
объекты и эти указатели в новом векторе действительны только до тех пор, пока строки в исходном векторе существуют, не изменяются в размерах и сам исходный вектор не изменяется.
И указатель на первый элемент нового вектора действителен только до тех пор, пока этот вектор существует и не изменяется.
Кажется достаточно простым
#include <algorithm>
#include <functional>
// ...
std::vector<char const*> result_owner(Words.size());
std::transform(begin(Words), end(Words), begin(result_owner),
std::mem_fn(&std::string::c_str));
const char* const* Result = result_owner.data();
Просто так Result
должен обеспечивать постоянное представление буфера, не означает, что буфер должен быть сам по себе const. Так что это просто еще один вектор, который мы получаем, проецируя Words
на std::string::c_str
член.
После этого Result
может быть просто еще одной ссылкой на result_owner.data();
,
Это, конечно, предполагает, что Result
не должен владеть буфером, на который он указывает. Владение необработанными указателями лучше избегать.
И пещерный способ сделать это:)
#include <iostream>
#include <vector>
#include <string>
#include <string.h>
using namespace std;
char **foo(const vector<string> &vec_of_strings)
{
int num_strings = vec_of_strings.size();
int max_str_len = 0;
for (int i=0;i<num_strings;i++)
{
if (max_str_len < vec_of_strings[i].length()) {
max_str_len = vec_of_strings[i].length();
}
}
// for null termination ...
max_str_len++;
char **result = (char **) malloc(num_strings);
for (int i=0;i<num_strings;i++)
{
result[i] = (char *) malloc(max_str_len);
strcpy(result[i],vec_of_strings[i].c_str());
}
return result;
}
int main(int argc, char **argv)
{
vector<string> vec_of_strings;
vec_of_strings.push_back("Long");
vec_of_strings.push_back("Livvvvvvvve");
vec_of_strings.push_back("The");
vec_of_strings.push_back("King");
const char * const * Result = foo(vec_of_strings);
for (int i=0;i<4;i++)
{
printf("%s\n",Result[i]);
}
}