What does 'alignment' component in format string mean?

According to this description:

Alignment: One of three characters ‘<’, ‘^’ or ‘>’; these are for left, middle and right alignment

First I thought it is about aligning within output column, like

// left
// right
// middle

But… this code

const std = @import("std");
const log = std.log;

pub fn main() void {
    const x: u32 = 0x0000_0001;
    log.info("x = 0x{X}", .{x});
    log.info("x = 0x{X:0>8}", .{x});
    log.info("x = 0x{X:0<8}", .{x});
    log.info("x = 0x{X:0^8}", .{x});

prints this:

info: x = 0x1
info: x = 0x00000001 // this is what I wanted to get
info: x = 0x10000000 // wtf?
info: x = 0x00010000 // wtf?

It looks like that field is about ordering but not about “alignment”!
So what does alignment field actually mean?

Additional note. My intention was to obtain same output like this C code does:

#include <stdio.h>

int main(void)
    unsigned int x = 0x00000001;
    printf("x = 0x%.8X\n", x);

What is a (most) correct Zig’s equivalent for C’s ‘%.8X’?

Doh… I catch the logic on. I specified width field (=8). The number printed is aligned within these 8 characters. All unoccupied positions are filled with a fiiler (‘0’ in my case). Hence the output which confused me.

The fill and alignment parameters are about decorating the output field as a string. The width parameter is going to determine how your number looks. You might want to specify a zero-fill on numbers with no alignment, though.

So {X:0>8} says “make a field 8 chars wide, fill it with ‘0’, then put the hex value at the ‘>’ side of the field.”

If you don’t specify a fill, what is the default for numbers, ‘0’ or ’ ’ (space)?

It is ' ':

log.info("x = '0x{X:>8}'", .{x});
log.info("x = '0x{X:^8}'", .{x});

info: x = '0x       1'
info: x = '0x   1    '

I wanted automatically added leading zeroes, so that numbers are always 8 chars long. This is exactly what C’s '%.8X' does. I tried '{X:08}' among others, but it does not work as needed.

1 Like