2015-09-25 2 views
5

У меня есть std :: string variable. И мне нужно поместить несколько байтов из массива unsigned chars. Я знаю первый байт и ногу.Поместите байты из массива unsigned char в std :: string с помощью функции memcpy()

Я могу использовать функцию std :: string :: assign. Я сделал это.

Но я хочу решить эту проблему правильно, используя функцию memcpy.

std::string newString; 
memcpy(&newString, &bytes[startIndex], length); 

Я знаю, что это неправильно. Я исследовал и нашел некоторые идеи, используя std :: vector.

Пожалуйста, помогите мне найти наиболее элегантное решение этой проблемы.

+4

Почему вы думаете, что 'assign()' не является «правильным способом»? – Barry

+0

«Правильно» означает «Я знаю, что это неправильно» =? – crashmstr

+0

@Barry Я хочу решить это двумя разными способами. Я изучаю язык C++. И поиск этого решения интересен для меня :) –

ответ

11

Поскольку мы только построения строки, есть std::string конструктор, который принимает два итератора:

template< class InputIt > 
basic_string(InputIt first, InputIt last, 
       const Allocator& alloc = Allocator()); 

, которые мы можем предоставить:

std::string newString(&bytes[startIndex], &bytes[startIndex] + length); 

Если мы не строить строку и вместо этого назначая к уже существующему, вы должны по-прежнему предпочитают для использования assign(). То есть именно то, что функция для:

oldString.assign(&bytes[startIndex], &bytes[startIndex] + length); 

Но если вы действительно настаиваете на memcpy() по какой-то причине, то вам необходимо убедиться, что строка на самом деле имеет достаточные данные для копирования в. А затем просто скопируйте его, используя &str[0] в качестве адреса назначения & dagger;:

oldString.resize(length); // make sure we have enough space! 
memcpy(&oldString[0], &bytes[startIndex], length); 

& крестик; Pre-C++ 11 технически не гарантировано, что строки хранятся в памяти смежно, хотя на практике это все равно было сделано.

+1

Почему downvote? – Barry

+0

IDK. похоже, кому-то не понравился ни один из ответов. – NathanOliver

+0

Я думаю, '' и bytes [startIndex + length] 'будет более соответствовать тому, что у вас есть (нет программируемой арифметики указателя). Но есть также строка ctor с 'const char *' и длиной: 'std :: string newString (& bytes [startIndex], length);' –

-1

Вы должны установить размер строки, так что будет правильно подобранный буфер для приема данных, и поверг константность из указателя вы получаете от data()

std::string newString; 
newString.resize(length); 
memcpy((char*)newString.data(), &bytes[startIndex], length); 

, конечно, все это находится в сфере неопределенного поведения, но довольно стандартно, тем более.

+0

В '& newString'? – Barry

+0

Вы правы, исправлены – shoosh

-3

Это хак и, как вы сказали неправильный путь, но это возможно, так как STL гарантирует, что std::string имеет смежную хранение:

std::string str(32, '\0'); 
std::strcpy(const_cast<char*>(str.data()), "REALLY DUDE, IT'S ILLEGAL WAY"); 

Конечно, вы можете использовать std::memcpy таким же образом (я использовал strcpy только копия завершается нулем строка) ...

В вашем случае:

str.resize(length); 
memcpy(const_cast<char*>(str.data()), bytes + startIndex, length); 
+0

А если строка, которую вы копируете, имеет более 32 байт? – Barry

+0

Конечно, вы должны «установить» подходящую строку (обратите внимание, 'resize()' not 'reserve()'!) – Nevermore

+2

, чтобы уточнить, что Nevermore означает «незаконным способом»: [* Изменение массива символов, доступ к которому осуществляется через данные это неопределенное поведение *] (http://en.cppreference.com/w/cpp/string/basic_string/data). Не делайте этого –