Jump to content
  • Advertisement
Sign in to follow this  
suliman

c++: sprintf but return chars. Possible?

This topic is 844 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi

Im doing:

.


//doStuff looks like this: void doStuff(char * n);

char temp[40];
sprintf(tempText,"Mytext: %d", myInt);
doStuff(tempText);

.

Is there a built in "getChar" function (in c or c++) so i can do this directly, like:

.

doStuff(getChar("Mytext: %d", myInt));
Edited by suliman

Share this post


Link to post
Share on other sites
Advertisement

If you don't mind a static buffer, you can fold those three lines in a "getChar" function (although the name is a bit misleading).

 

If you do mind a static buffer (and that is pronably a good thing), you need storage for the result, you could make your getChar return a std::string.

 

Last but not least you can write your own 'printf' function using varargs, and do whatever you desire, it might be a bit complicated though if you want to omit the text buffer.

Share this post


Link to post
Share on other sites

You could just overload doStuff() with varargs...

 

*grumble stdio grumble*

void doStuff(const char* formatString, ...) {
  va_list args;
  va_start(args, formatString);
  size_t strLen = vsnprintf(nullptr, 0, formatString, args);
  std::vector<char> buffer(strLen + 1);
  vsnprintf(buffer.data(), buffer.size(), formatString, args);
  va_end(args);

  //do stuff - your char* is now buffer.data()
}

or for more general usage

std::string stringf(const char* formatString, ...) {
  va_list args;
  va_start(args, formatString);
  size_t strLen = vsnprintf(nullptr, 0, formatString, args);
  std::string buffer(strLen + 1, 0);
  vsnprintf(&buffer[0], buffer.size(), formatString, args);
  va_end(args);
  buffer.pop_back();
  return buffer;
}

doStuff(stringf("derp %d herp", 42).c_str());

Share this post


Link to post
Share on other sites
You could abuse operator,:

void doStuff(const char*);

int main() {
    char buf[200];
    doStuff((sprintf(buf,"%d",myInt),buf));
}
Disclaimer: Don’t actually do this.

Share this post


Link to post
Share on other sites

If you are using C++ then you should be using iostream instead of stdio. Alternatively you could at least use snprintf.

Share this post


Link to post
Share on other sites
The iostream classes are often very annoying to work with when you have to deal with more complex substitutions. It can become very hard to read, very fast.

Something like boost::format is often a better idea because it combines a familiar, easier to read syntax with all the type safety C++ can offer you.

Share this post


Link to post
Share on other sites

I'm going to be contrary and advise not to do this.  What if your hypothetical getChar fails?

Share this post


Link to post
Share on other sites

What do you mean "if it fails"?

 

What i do now with sprintf could then also potentially fail no? I just want to compress the code i need to write. I end up in many such situations (must create a temporary char array that i inject floats and other stuff with %.2f etc and then pass it to a function that takes a "char *" parameter).

Edited by suliman

Share this post


Link to post
Share on other sites

Hi
Im doing:
.


//doStuff looks like this: void doStuff(char * n);

char temp[40];
sprintf(tempText,"Mytext: %d", myInt);
doStuff(tempText);
.
Is there a built in "getChar" function (in c or c++) so i can do this directly, like:
.
doStuff(getChar("Mytext: %d", myInt));

If we reinvent std::string, you can get half way there :P
class Chars
{
  char* c;
  size_t len;
public:
  explicit Chars( size_t length ) : c(new char[length]) len(length) {}
  Chars() : c() len() {}
  ~Chars() { delete[] c; }
  Chars( const Chars& o ) : c(o.len ? new char[o.len] : 0), len(o.len) { std::copy(o.c, o.c+len, c); }
  Chars( Chars&& o ) : c(o.c) len(o.len) { o.c = 0; o.len = 0; }
  Chars& operator=( const Chars& o ) { delete[] c; c = o.len ? new char[o.len] : 0; len = o.len; std::copy(o.c, o.c+len, c); return *this; }
  Chars& operator=(Chars&& o) { c = o.c; len = o.len; o.c = 0; o.len = 0; }

  const char* c_str() const { return c; }
        char* c_str()       { return c; }
}

Chars getChar( const char* fmt, ... )
{
    va_list arg;
    va_start(arg, fmt);
    size_t size = (size_t)vsnprintf( 0, 0, fmt, arg );
    Chars result = Chars( size );
    vsnprintf( result.c_str(), size, fmt, arg );
    va_end(argptr);
    return result;
}

Chars c = getChar("Mytext: %d", myInt);
doStuff(c.c_str());

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!