sprintf Question...

Started by
7 comments, last by StonerSunshine 20 years, 10 months ago
I''m working on a text class, and I want to use sprintf inside one of my class''s functions so that I can have formatted text. My problem is that I don''t know how to make my setString() function take a variable number of arguments so that I can make a call to sprintf inside. I tried just using the va_list variable type, but that didn''t work the way I thought it would. Can anyone give me any suggestions? Thanks in advance for your help.
Advertisement
If I remember correctly it goes something like this:


  void setString( char *str, ... ) {    va_list ap;    char buffer[1024];    va_start( ap, str );    vsprintf( buffer, str, ap );    va_end( ap );}  


~nz

// Website // Google // GameDev // NeHe // MSDN // OpenGL Extensions //
~neoztar "Any lock can be picked with a big enough hammer"my website | opengl extensions | try here firstguru of the week | msdn library | c++ faq lite
Awesome. That''s exactly what I needed. Thanks a lot!
Okay, I''ve run into another problem. I now have the setString()function working the way that I originally needed it to (thanks again for the help!), however I''ve found a fatal flaw... In order to update the value of the number that I format into my text, I have to call setString after updating my variable values. The scenario is a little like this:

void GameInit(void)
{
setString("Apples: %i", appleNum);
}

void GameMain(void)
{
// My problem is here. Incrementing this does nothing...
appleNum++;

// Unless I do this...
setString("Apples: %i", appleNum);
}

I think the solution that I''m seeking is a way to dereference a pointer that I pass into setString (which is calling vsprintf). I figured that if I have a pointer to the arguments going into the function, my text class''s drawString() function can just call vsprintf() at the beginning, and the pointer will be able to update the argument values without my calling setString() after every variable change. It''s possible for me to pass a pointer into setString():

setString(Apples: %i", &appleNum);

But, I don''t know how to dereference the argument inside the body of setString() so that I can format the text properly. It just formats it using the memory address. Is there a way to dereference pointers that are passed in as arguments to vsprintf()? If anyone has any suggestions, it would be greatly appreciated. Again, thanks in advance for any help...
Don''t do that. Reconstruct the string whenever you need it (ie, just before you output it). Have the actual format stored in the class that uses it (in some kind of toString member function, for instance).

Oh, and assuming MSVC, use _vsnprintf instead of vsprintf to save yourself from buffer overflows.

Kippesoep
Thanks for your reply. Hm, I think I understand. So, are you suggesting that the text class and its setString() function not handle formatting at all? I should instead do the formatting in each outside class, and just pass the already-formatted text into the setString() function to be printed?
My text drawer takes a string as a parameter and sets up vertex buffers to draw that string. I can then format the string using sprintf() outside the class before passing it to the class.
quote:Original post by StonerSunshine
So, are you suggesting that the text class and its setString() function not handle formatting at all? I should instead do the formatting in each outside class, and just pass the already-formatted text into the setString() function to be printed?


Basically, you should have something like this:


  class Foo{public :  void toString (char *buffer, int bufsize) const;private :  int m_bar;};void Foo::toString (char *buffer, int bufsize) const{  _snprintf (buffer, bufsize, "bar = %d", m_bar);}...  char buffer [1024];  myFoo->toString (buffer, sizeof (buffer));  //use buffer here...  


Much better, though, since you''re doing C++ anyway would be to have something like this:


  class Foo{public :  std::string toString () const;private :  int m_bar;};std::string Foo::toString () const{  std::ostringstream stream;  stream << "bar = " << m_bar;  return stream.str ();}...  //Display the string C way (as an example for how to use it)  printf ("%s", myFoo->toString ().c_str ());...  


Kippesoep
Ah, I see. Thanks again.

This topic is closed to new replies.

Advertisement