Преобразование строки в массив uint8_t в С++

Мне нужен объект std::string (например, имя) для массива uint8_t в С++. Функция reinterpret_cast<const uint8_t*> отклоняет мою строку. И так как я кодирую с использованием NS-3, некоторые предупреждения интерпретируются как ошибки.


person Carlo    schedule 05.10.2011    source источник
comment
Покажи свой код. Что вы подразумеваете под строковым объектом? std::string или указатель на char.   -  person selbie    schedule 05.10.2011


Ответы (3)


Если вам нужен указатель на данные string:

reinterpret_cast<const uint8_t*>(&myString[0])

Если вам нужна копия данных string:

std::vector<uint8_t> myVector(myString.begin(), myString.end());
uint8_t *p = &myVector[0];
person Robᵩ    schedule 05.10.2011
comment
Теоретически это не может быть завершено нулем - person Flexo; 05.10.2011
comment
Однако reinterpret_cast‹const uint8_t*›(myString.c_str()) будет работать (при условии, что myString является std::string). - person fbrereto; 05.10.2011
comment
@awoodland - правильно, но нулевое завершение не было требованием вопроса. И, учитывая, что он хочет uint8_t, а не char, можно с уверенностью предположить, что ему не нужна строка в стиле C. - person Robᵩ; 05.10.2011
comment
+1: std::vector отличная штука. Создает простую копию без memcpy или других вещей в стиле C, которые любят всплывать в ответах на такого рода вопросы. - person rubenvb; 05.10.2011
comment
@Rob: используйте .c_str() вместо &myString[0], поскольку std::string не обязательно быть непрерывным. - person Mooing Duck; 05.10.2011
comment
@awoodland: в то время как в С++ 03 он может не завершаться нулем, в С++ 11 стандарт требует нулевого завершения буфера. - person David Rodríguez - dribeas; 05.10.2011
comment
@rubenvb: Интересно, что, скорее всего, приведенный выше код в конечном итоге использует memmove (возможно, даже memcpy) под капотом. - person David Rodríguez - dribeas; 05.10.2011
comment
@DavidRodríguez-dribeas - Хорошо, я забыл это изменение среди всех действительно очевидных! - person Flexo; 05.10.2011
comment
@MooingDuck - Да, std::string не обязательно должно быть непрерывным, но std::string::operator[] обязательно. От Херба Саттера: [C++2003] требует, чтобы &str[0] извлекал указатель на непрерывные строковые данные (но не обязательно заканчивающиеся нулем!) См. lib.string.ops и < b>lib.string.access. - person Robᵩ; 05.10.2011
comment
@Rob: мне сказали, что С++ 03 этого не требует. Однако я вижу это по крайней мере в С++ 11. §21.4.1 / 5 ...for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size(). - person Mooing Duck; 05.10.2011
comment
MooingDuck, Роб: С++ 11 std::string имеет непрерывное хранилище, и если вы соедините разные части вместе (т. е. функция .c_str() должна быть O(1), поэтому не нужно копировать буфер), &s[0] и хранилище std::string::data()´ function gives you a null-terminated character array nonetheless. On the other hand, all popular current (pre-c++11) implementations do have contiguous std::string` ... - person rubenvb; 05.10.2011
comment
Дэвид: Я знаю, что он делает это под капотом, он просто прячет хрупкие и ненужные детали, поэтому код становится намного более читаемым, а ошибки для таких операций исчезают. - person rubenvb; 05.10.2011
comment
Есть ли гарантия, что uint8_t имеет то же представление, что и char? Если нет, то почему это справедливо? - person Clément; 16.11.2019

Строковые объекты имеют функцию-член .c_str(), которая возвращает const char*. Этот указатель можно привести к const uint8_t*:

std::string name("sth");

const uint8_t* p = reinterpret_cast<const uint8_t*>(name.c_str());

Обратите внимание, что этот указатель будет действительным только до тех пор, пока исходный строковый объект не будет изменен или уничтожен.

person sth    schedule 05.10.2011
comment
Есть ли способ сделать это в обратном порядке? Например, я хотел бы преобразовать массив uint8_t в c_str. Это возможно? - person Carlo; 05.01.2012

Если вам нужен фактический массив (а не указатель, как предлагали другие ответы, разница очень хорошо объясняется в этом ответе ), вам нужно использовать std::copy из <algorithm>:

std::string str = "foo";
uint8_t arr[32];
std::copy(str.begin(), str.end(), std::begin(arr));
person kraxor    schedule 10.01.2021