thecodingidiot.com

The VoiceCharacters and Strings

Characters and Strings

%c and %s are the two simplest specifiers: no numeric conversion, no sign handling, no base arithmetic. They are the right place to start because getting them right confirms that the variadic mechanism, the output helpers, and the return-value accounting all work before the integer conversions are added.

%c

%c prints a single character. The character is passed to printf as an int — the same promotion convention used by tci_isascii and the rest of libtci's character functions. Inside dispatch, va_arg(*args, int) reads the promoted value; the cast to unsigned char extracts the low byte before writing:

if (spec == 'c')
    return (tci_putchar_fd((unsigned char)va_arg(*args, int), 1));

The (unsigned char) cast is required for the same reason it appears in tci_isalpha: plain char may be signed, and values above 127 would be negative before the write if the cast were omitted. One byte is written; the function returns 1.

%s

%s prints a null-terminated string. tci_putstr_fd already handles this, including the NULL case:

if (spec == 's')
    return (tci_putstr_fd(va_arg(*args, char *), 1));

The NULL pointer behaviour — printing (null) — is what libc printf does on Linux. The tester expects this.

Run man 3 printf — search for "s conversion". The manual specifies that if the precision is given and is less than the string length, only that many bytes are written. Precision handling is covered on the flags page; for now, the full string is always written.

Build and test

Build and run the tester:

make re
bash test.sh

The remaining specifiers are stubs that return 0 — their rows will fail. That is expected at this stage. Confirm that the %c and %s rows pass before moving on. The integer specifiers are next.