I am trying to output 00001 instead of just 1, so I do this:

char pos[5];
sprintf(pos, "%05d", 1);
string Index = (string) pos;

It works just as I'd expect - if I cout << Index it says 00001

However, it is breaking something totally unrelated. On the next line, I access an element of a vector

geom_Vector3 T = Translations[SceneIndex];

(Translations was declared as vector<geom_Vector3> and filled before any of this).

If I get one of the elements of the vector with the 3 sprintf lines commented, it works fine. If I run the 3 sprintf lines before accessing the element, it is filled with garbage.

1) Why is it doing this??
2) Is there a better, less "c style" way to turn an integer in to a 5 digit integer with leading zeros that will prevent this all together?



Recommended Answers

All 5 Replies

Ok I found a different way (using iomanip.h)

stringstream IndexStream;
IndexStream << setfill('0') << setw(5) << Index;

This fixes the other memory error. My question remains though of why did the other way break??


> sprintf(pos, "%05d", 1);
Only that you forgot to count the \0, and it's trashing something else.

ah I see - dang that should be an error or a warning or something, shouldn't it??

It's the programmers responsibility to ensure the target buffer is sufficiently large enough to hold the maximum possible output size.

I think lint (or something like it) might catch it, but I'm not sure.

ah I see - dang that should be an error or a warning or something, shouldn't it??

In an ideal world, where compiler vendors care about perfectly diagnosing all errors in code, yes. In the real world, where compiler vendors prefer to focus attention on other things (eg performance) no.

In the real world it is undefined behaviour: it is actually a runtime error (tromping over memory) but compilers can't always predict runtime behaviour.

Your example;

char pos[5];
sprintf(pos, "%05d", 1);

can easily be converted into;

char pos[5];

//   and in some other source file

void some_function(char *x)
    sprintf(x, "%05d", 1);

so, at the point of the sprintf() call, the compiler has no information about the allocated length of string passed to some_function(). It is often technically VERY difficult for compilers to detect such cases.

Because of these possibilities (a compiler might be able to detect your case, but not technically able to detect the same problem after a minor code restructuring), the C++ standard simply defines both cases to be "undefined". This allows compiler vendors to simply ignore the thornier problems.
Compiler vendors therefore tend not to bother with detecting such things, particularly when programmers insist on the compilers giving features (fast compilation, good runtime performance) while remaining inexpensive.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.