Я использую UTFCPP для работы со строками в кодировке UTF-8, хранящимися в std :: string objetcs.
Я хочу перебрать кодовые точки. utf8 :: следующая ()
uint32_t next(octet_iterator& it, octet_iterator end);
кажется способ сделать это. Вот тестовая программа для иллюстрации использования:
std::string u8("Hello UTF-8 \u2610\u2193\u2190\u0394 World!\n");
std::cout << u8 << std::endl;
uint32_t cp = 0;
std::string::iterator b = u8.begin();
std::string::iterator e = u8.end();
while (cp = utf8::next(b,e))
printf("%d, ", cp);
Это извлекает все символы нормально, однако, программа выдает исключение NOT_ENOUGH_ROOM, которое указывает, что «Это становится равным конец во время извлечения кодовой точки «сразу после печати 10, который является управляющим символом новой строки ASCII:
Hello UTF-8 ☐↓←Δ World!
72, 101, 108, 108, 111, 32, 85, 84, 70, 45, 56, 32, 9744, 8595, 8592, 916, 32, 87, 111, 114, 108, 100, 33, 10,
terminate called after throwing an instance of 'utf8::not_enough_room'
what(): Not enough space
Очевидно, что предоставления конечного итератора, по-видимому, недостаточно для того, чтобы удержать utf8 :: next от попытки прочитать конец строки.
Меня также смущает функция utf8 :: unchecked :: next (), которая даже не использует конечный итератор. Как это знает, где остановиться? Ловит исключение нормальный управление потоком для определения конца строки
Очевидно, я что-то упустил.
Я думаю, что вы несете ответственность за проверку, равен ли итератор end () перед вызовом next ().
Это должно работать без исключения:
[...]
uint32_t cp = 0;
std::string::iterator b = u8.begin();
std::string::iterator e = u8.end();
while ( b != e ) {
cp = utf8::next(b,e);
printf("%d, ", cp);
}
Как правило, использование исключений для потока управления считается антишаблоном.