Каков правильный/лучший/самый простой способ преобразования строки c-style в std::string.
Преобразование должно принимать max_length и завершать строку в первом \0 char, если это происходит до чарта max_length.
Каков правильный/лучший/самый простой способ преобразования строки c-style в std::string.
Преобразование должно принимать max_length и завершать строку в первом \0 char, если это происходит до чарта max_length.
Эта страница на string::string
дает два потенциальных конструктора, которые будут делать то, что вы хотите:
string ( const char * s, size_t n );
string ( const string& str, size_t pos, size_t n = npos );
Пример:
#include<cstdlib>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
int main(){
char* p= (char*)calloc(30, sizeof(char));
strcpy(p, "Hello world");
string s(p, 15);
cout << s.size() << ":[" << s << "]" << endl;
string t(p, 0, 15);
cout << t.size() << ":[" << t << "]" << endl;
free(p);
return 0;
}
Вывод:
15:[Hello world]
11:[Hello world]
Первая форма рассматривает p
как простой массив и поэтому создаст (в нашем случае) строку длиной 15, которая, однако, печатает как строку с нулевым символом с 11 символами с cout << ...
. Наверное, не то, что вы ищете.
Вторая форма неявно преобразует char*
в строку, а затем сохранит максимум между ее длиной и указанным n
. Я думаю, что это самое простое решение, с точки зрения того, что вам нужно написать.
std::string str(c_str, strnlen(c_str, max_length));
В Кристиан Рау запрос:
strnlen
указан в POSIX.1-2008 и доступен в GNU glibc и библиотека времени выполнения Microsoft. Он еще не найден в некоторых других системах; вы можете вернуться к Gnulib.
std::string the_string(c_string);
if(the_string.size() > max_length)
the_string.resize(max_length);
Это на самом деле сложнее, чем кажется, потому что вы не можете вызвать strlen
если строка фактически nul не завершена. На самом деле, без некоторых
дополнительных ограничений, проблема практически требует изобрести нового
функция, версия strlen
, которая никогда не выходит за пределы определенной
длина. Однако:
Если буфер, содержащий строку c-style, гарантированно не менее
max_length
char (хотя, возможно, с '\0'
до конца),
то вы можете использовать конструктор длины адреса std::string
и
затем:
std::string result( c_string, max_length );
result.erase( std::find( result.begin(), result.end(), '\0' ), result.end() );
и если вы знаете, что c_string
является строкой, завершенной нулем (но, возможно,
дольше max_length
, вы можете использовать strlen
:
std::string result( c_string, std::min( strlen( c_string ), max_length ) );
Существует конструктор, принимающий два параметра указателя, поэтому код просто
std::string cppstr(cstr, cstr + min(max_length, strlen(cstr)));
это также будет столь же эффективным, как std::string cppstr(cstr)
, если длина меньше max_length
.
Вы хотите, чтобы этот конструктор:
std::string ( const string& str, size_t pos, size_t n = npos )
, передавая pos как 0. Строка const char * c-style будет неявно передана в строку const для первого параметра.
const char *c_style = "012abd";
std::string cpp_style = new std::string(c_style, 0, 10);