Printf Format Specification

3 min read
Cover Image for Printf Format Specification

I will portray one way of handling printf format specification in one's custom implementation of printf.

This article presumes one's familiarity with these concepts:

  1. Function Pointers

  2. Two Dimensional Arrays

  3. C Structs

The goal of this article is to highlight the focus areas in the video. It is an appendage to the video nugget content.


VIDEO: Printf Format Specification


MATRIX: Two-Dimensional Array

A basic implementation of a matrix, which is a two-dimensional array:

/* Two dimensional array */
char matrix[5][2] = {
    {'c', 'c'}, /* char print */
    {'s', 's'}, /* string print */
    {'i', 'i'}, /* int print */
    {'\0', '\0'}
};

Use of two-dimensional arrays to store chars that could be indexed into and used to check for member values availability:

sign = 0; /* first of a row */
function = 1; /* second index of a row */
for (row = 0; matrix[row][sign] != '\0'; row++)
{
    /* valid fmt specification */
    if (fmt_char == matrix[row][sign])
    {
        printf("Found: sign [%c], %c() function\n", matrix[row][sign], matrix[row][function]);
        return (0);
    }
}
printf("Not Found: sign [%c]\n", matrix[row][sign]);

C STRUCT: Usage as two-dimensional Array

Format specifier structure that has two members, a fmt_sign char and a fmt_func_ptr function pointer that takes one argument of type char:

/**
 * struct format_specifier - format specifier structure
 * @fmt_sign: fomat sign parameter
 * @fmt_func_ptr: format function pointer parameter
 */

typedef struct format_specifier
{
    char fmt_sign;
    void (*fmt_func_ptr)(char);
} fmt;

Basic Initialization of the Struct Two Dimensional Array, whereby each row has as its first index the format specifier sign and the format specifier function as the second index of the row. The array is terminated by a null row:

    /* struct two dimensional array */
    fmt fmt_specs[] = {
        {'c', char_print}, {'s', string_print},
        {'i', int_print}, {'\0', NULL}
    };

FUNCTION POINTER: Usage

Matching of the Format Specifier with the inputted fmt_char, when a valid specifier is matched in a row, the second index of the row gets called, hence the function pointer .fmt_func_ptr with its argument fmt_char :

for (row = 0; fmt_specs[row].fmt_sign != '\0'; row++)
    {
        /* valid fmt handling */
        if (fmt_char == fmt_specs[row].fmt_sign)
        {
            fmt_specs[row].fmt_func_ptr(fmt_char);
            return true;
        }
    }

Implementation Structure of Format Specifiers Functions, which gets called via the struct function pointer each time that the fmt_sign gets matched with the fmt_char:

void char_print(char fmt_char)
{
    /* Implementation */
}

void string_print(char fmt_char)
{
    /* Implementation */
}

void int_print(char fmt_char)
{
    /* Implementation */
}

Conclusion

The implementation of c printf format specification with structs, two-dimensional arrays and function pointers is more robust and accrues a clean code. Happy Coding and don't endeavour to code your dreams into reality.