thecodingidiot.com

The VoiceSetup

Setup

No new tools are needed for this chapter. The toolchain from f05/00 covers everything: gcc, make, valgrind.

Start from libtci

tci_printf extends libtci — the static library from c01. Create a new working directory and populate it with the c01 project as a starting point. If you completed c01 yourself, copy your working directory:

cp -r ~/c01-practice ~/c02-practice
cd ~/c02-practice

If you are starting fresh or want the reference version, clone the c01 companion repo and copy the solution:

git clone https://github.com/thecodingidiot-com/c01-the-toolkit.git
cp -r c01-the-toolkit/solution ~/c02-practice
cd ~/c02-practice

Verify the library still builds:

make re

You should see ar rcs libtci.a complete with no warnings. Twenty-nine object files, one archive.


Add the tci_printf stub

Create tci_printf.c with a function that compiles but does nothing yet:

#include "libtci.h"
#include <stdarg.h>
#include <unistd.h>
 
int     tci_printf(const char *fmt, ...)
{
    (void)fmt;
    return (0);
}

Add tci_printf.c to SRCS in the Makefile:

SRCS    = tci_memset.c tci_memcpy.c tci_memmove.c tci_memchr.c tci_bzero.c \
          tci_isascii.c tci_isalpha.c tci_isdigit.c tci_isalnum.c \
          tci_isspace.c tci_isupper.c tci_islower.c tci_isprint.c \
          tci_toupper.c tci_tolower.c \
          tci_strlen.c tci_strcpy.c tci_strncpy.c tci_strlcpy.c tci_strlcat.c \
          tci_strcmp.c tci_strncmp.c tci_strchr.c tci_strrchr.c tci_strnstr.c \
          tci_atoi.c \
          tci_calloc.c tci_strdup.c tci_strndup.c \
          tci_printf.c

Add the declaration to libtci.h:

int     tci_printf(const char *fmt, ...);

Run make re. Thirty object files, one archive, no warnings. The stub compiles but prints nothing — that changes on the next page.


Get the tester

Clone the companion repo and copy test.sh into your working directory:

git clone https://github.com/thecodingidiot-com/c02-the-voice.git
cp c02-the-voice/test.sh ~/c02-practice/

You will run bash test.sh at the end of each implementation page. Leave the clone where it is — you only need to do this once.


What printf[1] does

printf(fmt, ...) writes formatted text to standard output and returns the number of characters written. Internally, every C library printf eventually calls write(1, buf, n) — the POSIX system call that sends n bytes from buf to file descriptor 1. That is the only way to write to standard output without going through another library function.

tci_printf will do the same. It reads fmt character by character. When it encounters a % followed by a conversion specifier (d, s, x, etc.), it reads the next argument from the variable argument list, converts it to text, and writes the result. For every other character, it writes the character directly. It counts every byte written and returns the total.

The next page covers the variadic argument mechanism before any format string logic is added.

Footnotes

  1. printf - Wikipedia