How to use SetConsoleOutputCP?

how to print ©, ®, §, £ on console?

As you wish:

$ cat u.zig 

const std = @import("std");

pub fn main() !void {
    const str = "©, ®, §, £";
    std.debug.print("{s}\n", .{str});
    std.log.info("{s}", .{str});
    _ = try std.os.write(1, str);
    std.debug.print("\n", .{});
}
$ ./u 
©, ®, §, £
info: ©, ®, §, £
©, ®, §, £

Edit:
stupid me…
corrected first argument (0 -> 1) in std.os.write()
but, curiously enough, writing to stdin also worked.

Hello thank you for your help.

The following error appears in the console:

error: expected type ‘*anyopaque’, found ‘comptime_int’
_ = try std.os.write(0, str);

Could you please provide more context?

  • OS?
  • zig compiler version?
  • full example source that fails to compile

windows
zig 0.11

const std = @import(“std”);

pub fn main() !void {
const str = “©, ®, §, £”;
std.debug.print(“{s}\n”, .{str});
std.log.info(“{s}”, .{str});
_ = try std.os.write(0, str);
std.debug.print(“\n”, .{});
}

Yep, most likely, os.write() interface is different on Windows (there are no “file descriptors” there). I think Windows people will help you more, I have no experience with this OS.

1 Like
const std = @import("std");
const WinKernel = std.os.windows.kernel32;

pub fn main() !void {
    const a = WinKernel.SetConsoleOutputCP(65001);
    std.debug.print("{}\n\n", .{a});
    std.debug.print("{s}", .{"©, ®, §, £"});
}

I tried this code randomly and it worked. Now my only problem is when i don’t use type ‘a’ i get “unused local constant” error.

1 Like

How about the way presented for the offical Zig Hello, World! on the Language Reference?

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("{s}!\n", .{"©, ®, §, £"});
}

Output:

┬®, ┬«, ┬ğ, ┬ú!

If I remember right, Windows uses utf-16 Unicode encoding, not utf-8 as most Unices do.

const std = @import("std");
const WinKernel = std.os.windows.kernel32;

pub fn main() !void {
    _ = WinKernel.SetConsoleOutputCP(65001);
    std.debug.print("{}\n\n", .{a});    //NO NEED
    std.debug.print("{s}", .{"©, ®, §, £"});
}

I noticed that the error went away when I used underscore instead of const a. Now it works as I want.

const std = @import("std");
const WinKernel = std.os.windows.kernel32;

pub fn main() !void {
    _ = WinKernel.SetConsoleOutputCP(65001);
    std.debug.print("{s}", .{"©, ®, §, £"});
}

I’m glad I managed to do something like this even though I barely know programming :smiley:

const std = @import("std");
const WinKernel = std.os.windows.kernel32;

pub fn main() !void {
    _ = WinKernel.SetConsoleOutputCP(65001);
    std.debug.print("{s}", .{"🚀"}); //look, I can print rocket emoji on console!

}
2 Likes

Note that std.debug.print and std.log.info print to standard error, not standard out like std.io.getStdOut().writer().print does:

const std = @import("std");

pub fn main() !void {
    std.debug.print("{s}\n", .{"debug"});
    std.log.info("{s}", .{"info"});
    try std.io.getStdOut().writer().print("{s}\n", .{"stdout"});
}

Output wth standard error visible:

$ zig build run
debug
info: info
stdout

With standard error discarded:

$ zig build run 2>/dev/null
stdout

I guess there are no stdin (fd=0), stdout (fd=1) and stderr (fd=2) in Windows,
because there is no such a notion (“file descriptor” as positive integer) per se.

As well as /dev/null.

If you’re using the C runtime, those are definitely there: Low-Level I/O | Microsoft Learn

Not so much if you use the Win32 syscalls directly.

Thanks for clarification!

Judging by

Windows variant of std.os.write() does not use C runtime.

For having treated in depth with Linux and Windows. Regardless of the language, there are notable differences.
I did not see in Zig a substitution of the differences, this does not prevent to solve them, but of well distinguished in your soft when you work with Linux or Windows, the big problem with Windows is UTF16 in spite of the new console which supports UTF8, the APIs made available are always the same and of staggering complexity and sometimes solutions that we would have liked under Linux …