Strings in C++
-
Functionally there are the same excluding some obscure rules. Maybe one of the uber C++ people here will know. One thing is that char *TextString says a pointer to a character where char TextString [] actually does imply an array. Tim Smith I'm going to patent thought. I have yet to see any prior art.
Specifically, I am printing out text strings to my Display Window using DirectX. Basically I am storing a float variable into a text string: char fpsString[] = "Fps: 0000.000000"; float fps; fps = FrameCnt / TimeElapsed; sprintf(fpsString, "Fps: %f \0", fps); m_Font.Render(fpsString, 0, 0, g_Width, g_Height, DT_TOP | DT_RIGHT, 0xff000000); that function is defined as... void CDXFont::Render( char *TextString, int Xpos, int Ypos, int Width, int Height, DWORD Format, D3DCOLOR Color ) { // // Render the Font // Font->DrawText( 0, TextString, -1, // size of string or -1 indicates null terminating string &Rect, // rectangle text is to be formatted to in windows coords Format, // where to draw in viewport Color); // Color of text. } Don't worry about the DirectX and COM stuff, but I am wondering the proper way to go about printing a string which is a float number. This number might be really big or even negative at times, so that is why my parameter is a pointer. Am doing this the wrong way? I also want to format this number so that it is only about 2 or 3 decimal precision instead of 6. How would I be able to do this in C++? Thank You, CBerg
-
Specifically, I am printing out text strings to my Display Window using DirectX. Basically I am storing a float variable into a text string: char fpsString[] = "Fps: 0000.000000"; float fps; fps = FrameCnt / TimeElapsed; sprintf(fpsString, "Fps: %f \0", fps); m_Font.Render(fpsString, 0, 0, g_Width, g_Height, DT_TOP | DT_RIGHT, 0xff000000); that function is defined as... void CDXFont::Render( char *TextString, int Xpos, int Ypos, int Width, int Height, DWORD Format, D3DCOLOR Color ) { // // Render the Font // Font->DrawText( 0, TextString, -1, // size of string or -1 indicates null terminating string &Rect, // rectangle text is to be formatted to in windows coords Format, // where to draw in viewport Color); // Color of text. } Don't worry about the DirectX and COM stuff, but I am wondering the proper way to go about printing a string which is a float number. This number might be really big or even negative at times, so that is why my parameter is a pointer. Am doing this the wrong way? I also want to format this number so that it is only about 2 or 3 decimal precision instead of 6. How would I be able to do this in C++? Thank You, CBerg
The biggest problem in your code is that
sprintf()
may overflow the boundaries offpsString
iffps
is large. You should use proper C++ strings instead of legacy C character arrays, e.g.std::ostringstream fpsString;
// ...
fpsString << "Fps: " << fps;
m_font.Render(fpsString.str().c_str(), 0, 0, g_height, DT_TOP | DT_RIGHT, 0xff000000); -
The biggest problem in your code is that
sprintf()
may overflow the boundaries offpsString
iffps
is large. You should use proper C++ strings instead of legacy C character arrays, e.g.std::ostringstream fpsString;
// ...
fpsString << "Fps: " << fps;
m_font.Render(fpsString.str().c_str(), 0, 0, g_height, DT_TOP | DT_RIGHT, 0xff000000); -
Specifically, I am printing out text strings to my Display Window using DirectX. Basically I am storing a float variable into a text string: char fpsString[] = "Fps: 0000.000000"; float fps; fps = FrameCnt / TimeElapsed; sprintf(fpsString, "Fps: %f \0", fps); m_Font.Render(fpsString, 0, 0, g_Width, g_Height, DT_TOP | DT_RIGHT, 0xff000000); that function is defined as... void CDXFont::Render( char *TextString, int Xpos, int Ypos, int Width, int Height, DWORD Format, D3DCOLOR Color ) { // // Render the Font // Font->DrawText( 0, TextString, -1, // size of string or -1 indicates null terminating string &Rect, // rectangle text is to be formatted to in windows coords Format, // where to draw in viewport Color); // Color of text. } Don't worry about the DirectX and COM stuff, but I am wondering the proper way to go about printing a string which is a float number. This number might be really big or even negative at times, so that is why my parameter is a pointer. Am doing this the wrong way? I also want to format this number so that it is only about 2 or 3 decimal precision instead of 6. How would I be able to do this in C++? Thank You, CBerg
char fpsString [80]; float fps; fps = FrameCnt / TimeElapsed; snprintf(fpsString, 80, "Fps: %f \0", fps); 1. Trying to sprintf to a string like you were doing might cause problems on some platforms. 2. As someone pointed out, the sprintf might overflow the buffer. snprintf works great to avoid this problem without using STL which has its share of problems. Tim Smith I'm going to patent thought. I have yet to see any prior art.
-
OH GOD NO!!! std::ostringstream is slower than a dead man glued to the sidewalk. Tim Smith I'm going to patent thought. I have yet to see any prior art.
So how does one format a floating-point number without using stringstream or sprintf? --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ #include "witty-quote.h"
-
So how does one format a floating-point number without using stringstream or sprintf? --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ #include "witty-quote.h"
See my other post. Using stringstream just to avoid the buffer overrun issue can cause performance problems. snprintf was created just for this problem. A while back someone had a problem with std::hash being very slow. It was discovered that he was generating his keys with stringstream. Once he switched over to something with less overhead, it was MUCH faster. Don't get me wrong, stringstream is great. However in this case it is like using a 767 airliner for cropdusting. Tim Smith I'm going to patent thought. I have yet to see any prior art.
-
See my other post. Using stringstream just to avoid the buffer overrun issue can cause performance problems. snprintf was created just for this problem. A while back someone had a problem with std::hash being very slow. It was discovered that he was generating his keys with stringstream. Once he switched over to something with less overhead, it was MUCH faster. Don't get me wrong, stringstream is great. However in this case it is like using a 767 airliner for cropdusting. Tim Smith I'm going to patent thought. I have yet to see any prior art.
Just remember to null-terminate the buffer after the snprintf call, since snprintf won't terminate it if the buffer is too small. --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ Pinky, are you pondering what I'm pondering? I think so Brain, but how will we fit the hamster inside the accordion?
-
Just remember to null-terminate the buffer after the snprintf call, since snprintf won't terminate it if the buffer is too small. --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ Pinky, are you pondering what I'm pondering? I think so Brain, but how will we fit the hamster inside the accordion?
Thank You everybody. I would like to mention that it appears snprintf() is limited to Unix. I am using Visual C++ .NET and I had to call _snprintf() for this to work. I still had to be sure that my string declaration was fairly large to accomodate the whole number. char fpsString[22]; But, I could easily change decimal precision using the _snprintf(). I'm not sure about the speed issue, but if someone else could confirm that would be nice. CBerg
-
Just remember to null-terminate the buffer after the snprintf call, since snprintf won't terminate it if the buffer is too small. --Mike-- Personal stuff:: Ericahist | Homepage Shareware stuff:: 1ClickPicGrabber | RightClick-Encrypt CP stuff:: CP SearchBar v2.0.2 | C++ Forum FAQ Pinky, are you pondering what I'm pondering? I think so Brain, but how will we fit the hamster inside the accordion?
-
Are these statements equivalent? char *TextString char TextString[] Both declarations work with my program, but I'm not sure which is correct. Basically, I want to pass a string as a parameter, but when I define the function I don't really know the size of the string. Thank You. CBerg