Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacement for MS _vscprintf on MacOS/Linux?

Tags:

c++

string

As a learning experience I'm porting some stuff from Windows to MacOS and came across something like this:

void SomeClass::someFunction(const char* format, va_list args)
{
    int size = _vscprintf(format, args); // length after formatting
    std::string s;
    s.resize(size);
    vsprintf(&s[0]);
    ...
}

Now, as _vscprintf is Microsoft specific and I haven't found anything similar on Linux I thought I'd ask here.

Let's also assume this code is in some critical path and shouldn't have some extra overhead of heap allocation or such.

What is the recommended replacement for _vscprintf on MacOS/Linux?

Thanks!

like image 687
murrekatt Avatar asked Jan 24 '11 18:01

murrekatt


2 Answers

You can use vsnprintf instead;

  int _vscprintf (const char * format, va_list pargs) { 
      int retval; 
      va_list argcopy; 
      va_copy(argcopy, pargs); 
      retval = vsnprintf(NULL, 0, format, argcopy); 
      va_end(argcopy); 
      return retval; 
   }

Thanks to @dbasic for the more complete solution and @j-a for fixing the obvious errors.

like image 59
ismail Avatar answered Oct 12 '22 00:10

ismail


The previous solution is ok but has two bugs:

  1. The function va_copy has one parameter instead of two parameters.
  2. The call to function vsnprintf doesn't use the argcopy variable; it generates a corruption in the stack if you call vsnprintf again then.
int _vscprintf (const char * format, va_list pargs)
{ 
    int retval; 
    va_list argcopy;
    va_copy(argcopy, pargs); 
    retval = vsnprintf(NULL, 0, format, argcopy); 
    va_end(argcopy); 
    return retval;
}
like image 26
MarianoVolker Avatar answered Oct 12 '22 01:10

MarianoVolker