Библиотека
C ++ <iostreams>
не имеет встроенной поддержки для преобразования из одной кодировки текста в другую.Если вам нужно, чтобы ваш входной текст был преобразован из utf-8 в другой формат (скажем, например, базовые кодовые точки кодировки), вам нужно написать это преобразование вручную.
std::string data;
std::ifstream in("utf8.txt");
in.seekg(0, std::ios::end);
auto size = in.tellg();
in.seekg(0, std::ios::beg);
data.resize(size);
in.read(data.data(), size);
//data now contains the entire contents of the file
uint32_t partial_codepoint = 0;
unsigned num_of_bytes = 0;
std::vector<uint32_t> codepoints;
for(char c : data) {
uint8_t byte = uint8_t(c);
if(byte < 128) {
//Character is just a basic ascii character, so we'll just set that as the codepoint value
codepoints.push_back(byte);
if(num_of_bytes > 0) {
//Data was malformed: error handling?
//Codepoint abruptly ended
}
} else {
//Character is part of multi-byte encoding
if(partial_codepoint) {
//We've already begun storing the codepoint
if((byte >> 6) != 0b10) {
//Data was malformed: error handling?
//Codepoint abruptly ended
}
partial_codepoint = (partial_codepoint << 6) | (0b0011'1111 & byte);
num_of_bytes--;
if(num_of_bytes == 0) {
codepoints.emplace_back(partial_codepoint);
partial_codepoint = 0;
}
} else {
//Beginning of new codepoint
if((byte >> 6) == 0b10) {
//Data was malformed: error handling?
//Codepoint did not have proper beginning
}
while(byte & 0b1000'0000) {
num_of_bytes++;
byte = byte << 1;
}
partial_codepoint = byte >> num_of_bytes;
}
}
}
Этот код будетнадежно конвертировать из [правильно закодированного] utf-8 в utf-32, который обычно является самой простой формой для непосредственного преобразования в глифы + символы, хотя помните, что кодовые точки не являются символами .
Чтобы все было согласованно в вашем коде, я рекомендую, чтобы кодированный в utf-8 текст сохранялся в вашей программе с использованием std::string
, а кодированный в utf-32 текст - как std::vector<uint32_t>
.