Shuzheng
Shuzheng

Reputation: 13850

How to construct a format string in C with a variable or repeating number of placeholders?

I want to write a hexdump function. Therefore, I want to use sprintf with a format string like

"%c %c %c %c 0x%02X 0x%02X 0x%02X 0x%02X"

and then use this string with characters (or bytes) in printf().

However, I want the user to specify the line width, i.e., the number of bytes to be dumped on each line.

How do I construct a format string that has the given width, i.e. a width of 2 results in a format string of "%c %c 0x%02X 0x%02X"...

Upvotes: 0

Views: 245

Answers (3)

It is rather easy to construct such a format string.

However, the problem is calling sprintf with that format. There is no function in <stdio.h> that would let you pass in an array of arguments. Every single printf variant in the standard C requires you to decide the number of arguments at the compile time.

While it is possible to pass in less arguments, it doesn't help you with combined hex display such as

"%c %c %c %c  0x%02X 0x%02X 0x%02X 0x%02X"

and it gets rather tedious soon.

Unfortunately there is no easy way out - either you need to write your own sprintf variant, or use a loop instead.

Upvotes: 1

Nicolas Lykke Iversen
Nicolas Lykke Iversen

Reputation: 4205

Instead of constructing a format string using sprintf() only to use later with printf(), consider the following approach which is (basically) two passes over the input string:

void hex_dump(char *bytes, size_t bytes_len)
{
    const int DUMP_WIDTH = 16;

    for (int i = 0; i < bytes_len; i += DUMP_WIDTH)
    {
        for (int j = 0; j < DUMP_WIDTH; ++j)
        {
            if (i + j >= bytes_len) {
                printf(" ");
                continue;
            }
            char ch = bytes[i + j];
            if (isprint(ch))
            {
                printf("%c", ch);
            }
            else
            {
                printf(".");
            }
        }
        printf("   ");
        for (int j = 0; j < DUMP_WIDTH && i + j < bytes_len; ++j)
        {
            printf("0x%02x", bytes[i + j]);
            printf(" "); 
        }
        printf("\n");
    }
}

The function will output hexdump-like output controlled by the DUMP_WIDTH constant. Also, the output is properly aligned.

Upvotes: 1

Tiefan Ju
Tiefan Ju

Reputation: 520

I suggest to do like this:

I suggest to do like this:

void writeIntegersAsChar(char* str, int* source, int N)
{
    int i;
    for(i = 0; i < N; i ++)
    {
        sprintf(str + i, "%c", source[i]);
    }
}

Upvotes: 1

Related Questions