Наверное многие сталкивались с проблемой вывода русских букв в консоли Windows из программы на Zig. Объясняется это несоответствием кодировки консоли и кодировки программы. Я столкнулся с этим когда делал простую консольную утилиту на языке Zig и использовал кросс-компиляцию для нескольких платформ. Решением было бы использование кодировки UTF-8 в консоли Windows.

Вот этим мы сейчас и займемся.

Исследование проблемы

Собственно, суть проблемы понятна. Осталось понять как решить ее?

Беглое изучение вопроса довольно быстро привело к знанию о том, что в API Windows есть функция SetConsoleOutputCP, которая позволяет установить кодировку вывода консоли.

Дальнейшее изучение показало, что в Zig эта функция импортирована и доступна в стандартной библиотеке в пространстве имён std.os.windows.kernel32. Дальше, вооружившись этим знанием, уже дело техники.

Но в Zig 0.16 она была удалена из стандартной библиотеки. Покажу реализацию для версии 0.16.0.

Пример реализации

Вот пример:

const std = @import("std");
const builtin = @import("builtin");

extern "kernel32" fn SetConsoleOutputCP(wCodePageID: std.os.windows.UINT) callconv(.winapi) std.os.windows.BOOL;

pub fn main() !void {
    if (builtin.os.tag == .windows) {
        const CP_UTF8 = 65001;
        _ = SetConsoleOutputCP(CP_UTF8);
    }
    std.debug.print("Привет, мир!»\n", .{});
}

В данном примере мы проверяем, что мы работаем на Windows и устанавливаем кодировку вывода консоли в UTF-8. Затем выводим строку "Привет, мир!»".

Примечание: пример работает только на Windows 10 и новее. Получить тот же результат на более старых версиях Windows мне не удалось.