Как напечатать строку Unicode в Zig?
Я пытался закодировать строковую структуру Unicode, и хотя стандартная библиотека предоставляет
unicode
модуль, похоже, он не предоставляет способ распечатать фрагмент
u16
. Я пробовал это:
const std = @import("std");
const unicode = std.unicode;
const stdout = std.io.getStdOut().outStream();
pub fn main() !void {
const unicode_str = unicode.utf8ToUtf16LeStringLiteral(" hello! ");
try stdout.print("{}\n", .{unicode_str});
}
Это выводит:
[12:0]u16@202e9c
Есть ли способ распечатать строку юникода ([]u16
) без преобразования его обратно в строку, отличную от Unicode ([]u8
)?
1 ответ
И то и другое
[]const u8
и
[]const u16
хранить закодированные кодовые точки Unicode. Кодовые точки Unicode попадают в диапазон 0..1114112, поэтому фактическая строка Unicode с одним индексом массива для каждой кодовой точки должна быть
[]const u21
. И utf-8, и utf-16 требуют кодирования для кодовых точек, которые не подходят. Если нет причины совместимости для utf-16 (например, некоторых функций Windows), вам, вероятно, следует использовать
[]const u8
строки юникода.
Чтобы напечатать utf-16 в потоке utf-8, вам необходимо декодировать utf-16 и перекодировать его в utf-8. В настоящее время нет спецификатора форматирования, который бы делал это автоматически.
Вы можете преобразовать всю строку сразу, требуя выделения:
const utf8string = try std.unicode.utf16leToUtf8Alloc(alloc, utf16le);
Или без выделения:
var writer = std.io.getStdOut().writer();
var it = std.unicode.Utf16LeIterator.init(utf16le);
while (try it.nextCodepoint()) |codepoint| {
var buf: [4]u8 = [_]u8{undefined} ** 4;
const len = try std.unicode.utf8Encode(codepoint, &buf);
try writer.writeAll(buf[0..len]);
}
Обратите внимание, что это будет очень медленно без использования буферизованной записи, если вы пишете где-то, для чего требуется системный вызов.