Скопируйте std :: u8string в строку в стиле c из utf8 символов - PullRequest
3 голосов
/ 02 июля 2019

Копировать строку без кодировки в 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 ]

8 голосов
/ 02 июля 2019

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;
}

Поскольку собственный copy() метод u8string не может использоваться для непосредственного включения нулевого терминатора, я не буду использовать его при копировании в необработанный char8_t*.

3 голосов
/ 02 июля 2019

В дополнение к использованию 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;
}
0 голосов
/ 02 июля 2019

Мне кажется, что было бы проще просто использовать встроенное копирование и предоставить .data() коду C:

std::u8string orig = u8"abc";
auto copy = orig;
c_api(copy.data(), copy.size());

Делая это, вы позволяете скопированной строке управлять ееСобственное время жизни и размер на равных с данными.Это работает равномерно для любого типа символа std::basic_string.В качестве дополнительного бонуса, он также работает для std::vector.

...