Bobbybobbobbo
Bobbybobbobbo

Reputation: 51

C - how does sprintf() work?

I'm new to coding in C and was writing a program which needs to create custom filenames that increment from 0. To make the filenames, I use sprintf() to concatenate the counter and file extension like so:

int main(void)
{
    // do stuff
    int count = 0;
    while (condition == true)
    {
        char filename[7];
        sprintf(filename, "0%02d.txt", count) //count goes up to a max of 50;
        count++; 

        //check condition
    }
    return 0;
}

However, every time

sprintf(filename, "0%02d.txt", count);

runs, count gets reset to 0.

My question is, what does sprintf() do with count? Why does count change after being passed to sprintf()?

Any help would be much appreciated.

EDIT: Sorry, I haven't been too clear with the code in my question - I'm writing the program for an exercise on an online course, and count goes up to a max of 50. I've now changed my code to reflect that. Also, thanks for telling me about %04d, I was using a complicated if statement to determine how many zeroes to add to my filename to make it 3-digit.

Upvotes: 0

Views: 1229

Answers (2)

evaitl
evaitl

Reputation: 1395

I think it is likely the sprintf. "0%02d.txt" is 7 chars. The null at the end of the string will go in the next location, which is likely the count on the stack. On a little endian machine (x86), that likely means the bottom byte of count gets zeroed out in every sprintf().

As other folks said. Make the filename buffer larger.

Upvotes: 1

Rudy Velthuis
Rudy Velthuis

Reputation: 28806

Despite the title of the question, this has nothing to do with sprintf(), which probably works as expected, but everything with count.

If count is a global variable (i.e. outside any functions), then it should keep its value between function calls. So that is probably not the case.

If it is a local variable (declared inside the function), then it can have any value, since these lose their value when the function ends and don't get initialized when the function is run again. It can be always 0, but under different circumstances, it can just as well be something else. In other words, the value is more or less undetermined.

To have a local variable keep its value between function calls, make it static.

static int count = 0;

But note that when you stop and run the program again, it will start as 0 again. That means you would possibly overwrite 000.txt, then 001.txt, etc.

If you really want to avoid duplicate file names, you will have to be more sophisticated, and see which files are already there, determine the highest number, and increment that by one. So you don't use a variable, you check the files that already exist. That is far more work, but the only reliable way to avoid overwriting existing files with such numbered file names.


FWIW, I would use something like "00%04d.txt" as format string, so you get files 000000.txt, 000001.txt, etc. which look better in an alphabetically sorted file listing than 000.txt, 001.txt, 0010.txt, 0011.txt, 002.txt, etc. They are also easier to parse for their number.

As Weather Vane noticed, be sure to make your buffer a little larger, e.g.

char filename[20];

A buffer that is too small is a problem. One that is too large is not, unless it is huge and clobbers up the stack. That risk is very small with 20 chars.

Upvotes: 1

Related Questions