tags:

views:

67

answers:

3

.* The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

#define SUFF ".txt"
#define MAX_STR 50

fileName[MAX_STR];
name ="myFile"

sprintf( fileName, "%s%s", name, SUFF ); //fileName = "myFile.txt"

Now I want to bound the strings with precision.

The basic thing I am trying to do (but with more dynamic calculations, which is why I am using the '*') is:

sprintf( fileName, "%.*s%.*s", 46, 4, name, SUFF );

However, even this create a run time exception.

More specifically:

sprintf( fileName, "%.*s%.*s",
         MAX_STR - (int) sizeof(SUFF), (int) sizeof(SUFF),
         name, SUFF );
+3  A: 

You have the order of the variable arguments wrong. The width argument goes with the object argument (it must immediately precede the object).

sprintf(fileName, 
        "%.*s%.*s", 
        MAX_STR - (int) sizeof(SUFF), // precision and...
        name,                         // ...object
        (int) sizeof(SUFF),           // precision and...
        SUFF                          // ...object
       ); 

Even if you are going to use the width specifier, it is still far better to use snprintf instead of sprintf.

James McNellis
ahh, I see how it works, thanks...
Tommy
+2  A: 

You mixed up the order of the arguments in the final sprintf. It should be like this:

sprintf( fileName, "%.*s%.*s",
         MAX_STR - (int) sizeof(SUFF), name,
         (int) sizeof(SUFF), SUFF );

There are some additional things worth noting here:

  1. sprintf is the wrong tool for the job if you're allocated strings defined at compile time, and passing precision like this is unnecessary since the sizes are also fixed. Something like char fileName[] = "myFile" SUFF; is more than sufficient.
  2. A good compiler (I'm guessing you're using MSVC by your archaic style), will actually parse out the arguments to sprintf and tell you at compile time about your error. Take a look at the format attribute.
Matt Joiner
+1  A: 

An oft-easier option is asprintf() - if sufficiently portable (used to be an issue last millenium when I was using C rather than C++) - hope it's standardised and universal now. It's not as fast as it mallocs memory that you need to explicitly free afterwards, but it lets the programmer think in terms of formatting whatever the inputs are, without having to jump through hoops or add arbitrary restraints on their size, which avoids many small bugs and limitations.

Tony