Petr Přikryl
Petr Přikryl

Reputation: 1812

snprintf() does not work for modifying a string in-place

char symbols[16] = "";
int index = 0;
while (1)
{
     if (index % 2)
         snprintf(symbols, sizeof symbols, "a%s", symbols);
     else
         snprintf(symbols, sizeof symbols, "b%s", symbols);

     index++;

     printf("%s\n", symbols);
}

How output looks: a => bb => aaa => bbbb

I want the output looks: a => ba => aba => baba

Upvotes: 2

Views: 741

Answers (2)

William Morris
William Morris

Reputation: 3684

It can be done without snprintf too, of course:

char symbols[16] = "";
for(int i=0; i<15; ++i) {
    memmove(&symbols[1], symbols, i);

    if (i % 2) {
        symbols[0] = 'a';
    } else {
        symbols[0] = 'b';
    }
    printf("%s\n", symbols);
}

Upvotes: 0

hmjd
hmjd

Reputation: 122001

This is undefined behaviour. From the C99 standard section 7.19.6.5 The snprintf function:

The snprintf function is equivalent to fprintf, except that the output is written into an array (specified by argument s) rather than to a stream. If n is zero, nothing is written, and s may be a null pointer. Otherwise, output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array. If copying takes place between objects that overlap, the behavior is undefined.

You will need to make a copy of symbols for use as an argument in the snprintf() calls:

char symbols[16] = "";
char symbols_copy[16];
int index = 0;
while (index++ < 15)
{
     memcpy(symbols_copy, symbols, sizeof(symbols));

     if (index % 2)
         snprintf(symbols, sizeof symbols, "a%s", symbols_copy);
     else
         snprintf(symbols, sizeof symbols, "b%s", symbols_copy);

     printf("%s\n", symbols);
}

See demo http://ideone.com/GvnW7D .

Upvotes: 7

Related Questions