tags:

views:

86

answers:

3

Lookign at:
http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

for string (%.Ns) precision.

When I use sizeof or a #define length in the precsion it reads it as actual text.

Why is this? What are the rules of this? Does it have to be an integer value only?

i.e. -

buffer[50];

sprintf (buffer, "%.sizeof(buffer)s", string);  

or

#define MAX_LEN

sprintf (buffer, "%.MAX_LENs", string);  

Thanks

+12  A: 

Anything inside quotation marks is part of the string, and the compiler won't even think of touching it. Instead, you can use a '*' to let sprintf know your precision is an extra argument it can read. Also, you need the '.' before your precision, or otherwise it will be a pad-width instead.

sprintf(buffer, "%.*s", (int) sizeof(buffer), string);
aschepler
So in your example the'*' will be replaced with sizeof(buffer)? (sorry, I did have the "." in there just updated the question, however it still prints as a string.)
Tommy
OIC- '*' The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
Tommy
@aschepler: Except that `sprintf` will expect an `int` argument for `*` specifier, and you are passing the result of `sizeof`, which is certainly not an `int`. You have to explicitly cat the result of `sizeof` to `int` before passing it to `sprintf`.
AndreyT
do we want strlen which returns a "size_t" which should be an integer on windows...
Tommy
@AndreyT Quite true. I'll fix it. @Tommy No, not strlen(), because it searches for a '\0' to figure out where a string ends, and if the buffer is uninitialized, you have no clue where or whether there is a '\0' in buffer. Besides, it also returns size_t, not int.
aschepler
ok got it, thanks
Tommy
+1  A: 

That's the way strings work; anything inside the "s will be interpreted as a string. You can use #defined numeric constants if you want like this:

#define MAX_LEN 50
buffer[50];
sprintf (buffer, "%" #MAX_LEN "s", string);

That uses compile-time string concatenation.

Nathon
Close, but the stringizing operator is only recognized inside preprocessor directives, like macro definitions. You'll need to introduce several layers of helper macros to make this work.
Ben Voigt
Aww, that's what I get for not trying it. aschelper was right anyway though; "%.*s" is the way to go.
Nathon
+1  A: 

Not relevant to your example but important in similar situations if you a define like this:

#define SOMEONES_MIDDLE_NAME "Ray"

You can insert it into strings like this:

sprintf(buffer, "Billy " SOMEONES_MIDDLE_NAME " Cyrus", sizeof(buffer));

The compiler will automagically collect string literals into single blocks.

Daniel