c++ linux std::string to bytearray
Мне нужно преобразовать std::string в массив байт(unsigned char) с кодировкой UTF-16LE. В windows с помощью std::wstring, я смог это сделать вот так:
vector<Byte> stringToBytes(const std::wstring& str)
{
vector<Byte> res;
res.reserve(str.size() * 2);
for (auto& item : str)
{
res.push_back(item & 255);
res.push_back((item >> 8) & 255);
}
return res;
}
И в результате получается нечто подобное:
То есть 2 байта на 1 символ. А как сделать такое в линуксе, но при помощи std::string?
Ответы (1 шт):
Автор решения: KoVadim
→ Ссылка
Вот пример, как это сделать "ручками". Если нужно много разных кодировок - воспользуйтесь какой либо библиотекой, например, iconv.
#include <iostream>
#include <vector>
#include <memory>
#include <iomanip>
using data_t = std::vector<unsigned char>;
void add_char(data_t& v, unsigned short c)
{
v.push_back(c & 0xFF);
v.push_back((c & 0xFF00) >> 8);
}
int main()
{
std::wstring a = L"привіт ?";
data_t data;
for (wchar_t c : a) {
if (c < 0x10000) {
add_char(data, c );
} else {
// суррогатные пары
add_char(data, 0xD800 | (c >> 16));
add_char(data, 0xDC00 | c);
}
}
for (unsigned char c : data) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)c << " ";
}
}
Но если хочется std::string, тогда нет проблем:)
std::vector<char> v;
std::string s = "test";
for (char c : s) {
v.push_back(c);
v.push_back(0);
}
как выяснилось, у автора скорее всего utf-8, но он об этом не знает. В этом случае можно даже встроенными средствами с++.
#include <iostream>
#include <vector>
#include <iomanip>
#include <codecvt>
int main()
{
std::string str = u8"привіт ?";
std::u16string u16_conv = std::wstring_convert<
std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(str);
std::vector<unsigned char> v;
for (char16_t c : u16_conv) {
v.push_back(c & 0xFF);
v.push_back((c & 0xFF00) >> 8);
}
for (auto c : v) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (unsigned int)c << " ";
}
}
правда с 17 плюсов этот код немного задеприкейчен...