Скопируйте std::u8string в строку в стиле c из utf8 символов
Копировать строку без кодировки в c-строку довольно просто:
auto to_c_str(std::string const& str) -> char* {
auto dest = new char[str.size() + 1];
return strcpy(dest, str.c_str());
}
Но как я могу сделать это с std::u8string
? Есть ли алгоритм STL, который может помочь с этим?
Я попробовал это:
auto to_c_str(std::u8string const& str) -> char8_t* {
auto dest = new char8_t[str.size() + 1];
return std::strcpy(dest, str.c_str());
}
Но конечно, std::strcpy
не перегружен для строк utf8.
3 ответа
В дополнение к использованию std::memcpy
, вы можете использовать std::u8string::copy
а также std::copy
,
auto to_c_str(std::u8string const& str) -> char8_t* {
auto dest = new char8_t[str.size() + 1];
str.copy(dest, str.size(), 0);
dest[str.size()] = u8'\0';
return dest;
}
auto to_c_str(std::u8string const& str) -> char8_t* {
auto dest = new char8_t[str.size() + 1];
std::copy(str.begin(), str.end(), dest);
dest[str.size()] = u8'\0';
return dest;
}
strcpy
не требуется, так как вы уже знаете длину того, что вы хотите скопировать, поэтому используйте memcpy
:
char8_t* to_c_str(std::u8string const& str) {
auto dest = new char8_t[str.size() + 1];
return static_cast<char8_t*>(std::memcpy(dest, str.data(), str.size()+1));
}
или же std::copy
:
char8_t* to_c_str(std::u8string const& str) {
auto dest = new char8_t[str.size() + 1];
std::copy(str.data(), str.data() + str.size() + 1, dest);
return dest;
}
Поскольку u8string
собственный copy()
метод не может быть использован для непосредственного включения нулевого терминатора, я бы не использовал его при копировании в raw char8_t*
,
Мне кажется, что было бы проще использовать встроенное копирование и обеспечить .data()
к коду C:
std::u8string orig = u8"abc";
auto copy = orig;
c_api(copy.data(), copy.size());
Делая это, вы позволяете скопированной строке управлять собственным временем жизни и иметь размер наравне с данными. Это работает равномерно для любого типа символа std::basic_string
, В качестве дополнительного бонуса, он также работает для std::vector
,