Какой самый эффективный способ преобразовать массив строк STL в массив const char *? - PullRequest
2 голосов
/ 08 июля 2010

У нас есть:

 std::string string_array[2];

 string_array[0] = "some data";

 string_array[1] = "some more data";

 char* cstring_array[2];

Какой самый эффективный способ скопировать данные из string_array в cstring_array? Или передать string_array в функцию, нужно "const char* cstring_array[]"?

Ответы [ 6 ]

12 голосов
/ 08 июля 2010

Функция, которая принимает char const *, написана так, чтобы принимать только одну строку за раз, а не массив строк.Чтобы передать std::string в такую ​​функцию, просто вызовите функцию с your_string.c_str() в качестве параметра.

Edit: для функции, которая принимает массив строк, очевидный выбор (по крайней мере для меня)было бы написать минимальный интерфейс, который позволяет вам передать vector<std::string>:

// The pre-existing function we want to call.
void func(char const *strings[], size_t num) { 
    for (size_t i=0;i<num; i++)
        std::cout << strings[i] << "\n";
}

// our overload that takes a vector<string>:
void func(std::vector<std::string> const &strings) { 
    std::vector<char const *> proxies(strings.size());

    for (int i=0; i<proxies.size(); i++)
        proxies[i] = strings[i].c_str();
    func(&proxies[0], proxies.size());
}
4 голосов
/ 08 июля 2010

Используйте string::c_str, чтобы получить постоянный указатель на символ.

3 голосов
/ 08 июля 2010

Просто используйте:
string_array[0].c_str()
string_array[1].c_str()

См. c_str () :

const charT * c_str ()const basic_string Возвращает указатель на завершенный нулем массив символов, представляющих содержимое строки.

1 голос
/ 08 июля 2010

Вы можете получить доступ к версии c-string, передав string_array [1] .c_str () любой функции, для которой требуется строка.

Однако помните, что возвращаемый указатель зависит от stl :: string! Если вы возьмете указатель, а затем освободите строку, у вас будет неверный указатель

0 голосов
/ 09 июля 2010

Похоже, у вас возникли проблемы с массивами.Как отметил Брайан, индексы массива начинаются с 0, а не с 1. Таким образом, ваши два strings равны string_array[0] и string_array[1], , а не string_array[1] и string_array[2].

Также, если ваша функция принимает параметр const char* cstring_array, то ваша переменная char* cstring_array[2], вероятно, не то, что вы хотите.Если бы вы передавали его как есть, вы бы по существу передавали char**, а не char*, поскольку вы можете считать имя массива эквивалентным указателю на его первый элемент .

Когда вы представили свой вопрос, вы могли бы сделать что-то вроде следующего (исправление ошибки индексации и допущение, что упомянутая вами функция называется myFunction):

...
cstring_array[0] = string_array[0].c_str( );
cstring_array[1] = string_array[1].c_str( );

myFunction (cstring_array[0]);
myFunction (cstring_array[1]);
...

Однако более простой эквивалент, который вообще не требует cstring_array:

...
myFunction (string_array[0].c_str( ));
myFunction (string_array[1].c_str( ));
...

Или, если вы намеревались передать один массив char, содержащийобе строки (что возможно из моей интерпретации вопроса), тогда вы действительно хотите сказать, что хотите создать единственную строку, представляющую собой конкатенацию ваших исходных двух:

...
std::string str = string_array[0] + string_array[1];

myFunction (str.c_str( ));
...

Надеждаэто помогает!

РЕДАКТИРОВАТЬ: учитывая комментарии, которые появились после того, как я написал это, я бы сказал, что первый пример близок к тому, что вам нужно.Я бы сделал следующее (где N - количество записей в любом массиве):

...
for (int i = 0; i < N; i++)
    cstring_array[i] = string_array[i].c_str( );

myFunction (cstring_array);
...

Это единственный возможный подход.Не существует стандартной функции (AFAIK), которая, учитывая массив string, даст массив char*.Я подозреваю, что причина в том, что: - Это не то, что нужно делать часто, поэтому мало что для того, чтобы такая функция была широко доступна.- Если бы была такая функция, она, скорее всего, была бы очень похожа на вышеприведенную в любом случае, и в этом случае она настолько тривиальна, что не нужна.

В принципе, чтобы ответить на ваш вопрос, я не думаю, что тамявляется более эффективным методом, и даже если бы существовала стандартная библиотечная функция для этого, он все равно использовал бы этот подход.

0 голосов
/ 09 июля 2010

Два разных вопроса, правда. Чтобы перейти к функции, просто вызовите c_str(). Чтобы скопировать, просто наберите strncpy() и вспомните, что я сказал о переходе к функциям.

Имейте в виду, что std :: string может содержать '\ 0' без фактического завершения. При таких условиях вы получите только часть строки. Если вы пытаетесь скопировать такие данные, вам нужно использовать memcpy().

...