Problem with sprintf function, last parameters are wrong when written
So I use sprintf
sprintf(buffer, "%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID, dDistance, nConfig);
But when I print the buffer I get the 2 last parameters wrong, they are lets suppose to be 35.0000 and 0 and in the string they are 0.00000 and 10332430 and my buffer is long enough and all the other parameters are good in the string
Any idea? Is there a length limit to sprintf or something?
I checked the types of all the numbers and they are right, but what seems to be the problem is the dDistance. When I remove it from the sprint, the nConfig gets the right value in the string, but when I remove nConfig, dDistance still doesn't get the right value. I checked and dDistance is a double. Any idea?
Since people don't seem to believe me I did this :
char test[255]={0};
int test1 = 2;
double test2=35.0开发者_如何转开发0;
int test3 = 0;
sprintf(test,"%d|%f|%d",test1,test2,test3);
and I get this in my string:
2|0.000000|1078034432
I'd check to make sure your argument types match up with your format string elements. Trying to display a double as an integer type (%d) or vice versa can give you strange output.
Are you sure your data types match your format spec?
Try printing out your data, that is, create a printf with the same format and see what happens that is:
printf("%f|%f|%f|%f|%f|%f|%d|%f|%d", x, y, z, u, v, w, nID,dDistance, nConfig);
Try using streams, for example
stringstream ss;
ss << x << "|" << y << "|" << z << "|" << u << "|" << v << "|" << w << "|"
<< nID << "|"<< dDistance << "|"<< nConfig;
string s = ss.str();
and then do something with s;
What size are long and int?
If nID is a long being printed with an 'int' format and sizeof(int)
!= sizeof(long)
then you get misaligned data access (in the sense that the alignment is not correct) from there on.
Which compiler are you using? GCC should diagnose the problem without difficulty if that is the trouble. Similarly, if nID is a 'long long', you could have problems.
To answer your question - yes, there is an lower-bound on the upper-limit of the length of string that sprintf()
must be able to handle. The number is 509 for C89 systems, and 4095 for C99 systems.
To be precise, C99 says (fprintf()
, section §7.19.6.1, para 15):
The number of characters that can be produced by any single conversion shall be at least 4095.
There is no further qualification on sprintf()
.
With fixed version of amended example converted into compilable code:
#include <stdio.h>
int main(void)
{
char test[255] = {0};
int test1 = 2;
double test2 = 35.00;
int test3 = 0;
sprintf(test, "%d|%f|%d", test1, test2, test3);
puts(test);
return(0);
}
I get the output I would expect:
2|35.000000|0
To be getting the output you show, you have to be working with a very weird setup.
- What platform are you on?
The behaviour you are showing indicates that the sprintf()
function you are using is confused about the alignment or size of something. Do you have a prototype in scope - that is, have you #included <stdio.h>
? With GCC, I get all sorts of warnings when I omit the header:
x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:9: warning: implicit declaration of function ‘puts’
But even with test2
redefined as a float
I get the correct result.
If I change test2
into a long double
, then I get a different set of warnings and a different result:
x.c: In function ‘main’:
x.c:8: warning: implicit declaration of function ‘sprintf’
x.c:8: warning: incompatible implicit declaration of built-in function ‘sprintf’
x.c:8: warning: format ‘%f’ expects type ‘double’, but argument 4 has type ‘long double’
x.c:9: warning: implicit declaration of function ‘puts’
2|0.000000|0
This is closer to what you are seeing, though far from identical.
Since we don't have the platform information, I'm suspicious that you are working with a truly ancient (or do I mean buggy?) version of C. But I'm still at something of a loss to see how you get what you show - unless you're on a big-endian machine (I'm testing on Intel Mac with MacOS X 10.6.2) ...pause... on a SPARC machine running Solaris 10, without #include <stdio.h>
and with long double test2 = 35.0;
, I get:
gcc -O x.c -o x && ./x
x.c: In function 'main':
x.c:8: warning: incompatible implicit declaration of built-in function 'sprintf'
2|-22446048024026502740613283801712842727785152907992454451420278635613183447049251888877319095301502091725503415850736723945766334416305449970423980980099172087880564051243997662107950451281495566975073444407658980167407319222477077473080454782593800009947058951029590025152409694784570786541673131117073399808.000000|0
That's different; it also generates 321 characters of output, so there's a buffer overflow in there - it is better to use 'snprintf()
' to prevent that from occurring. When things are declared properly, of course, I get the expected result.
So, can you post compilable code that shows your problem, instead of a snippet that does not? And can you identify your platform - machine type, operating system version, compiler version (and maybe C library version)?
Is dDistance of type double? It looks like your %f is only grabbing four bytes of a double and then the next four bytes are treated as an integer, the real integer value is then ignored.
This question is tagged C++; are you able to use std::ostringstream which would eliminate any possible problems with the conversion string?
精彩评论