_vscprintf?

Started by
7 comments, last by snk_kid 18 years, 10 months ago
Today I tried to set up some dev-c++ projects for my game engine to see if it'ld compile. My problem is that Dev-C++ says that _vsprintf is undefined. I tried to search for _vscprintf in all the files in D:\Dev-cpp\Include (and subdirs) and couldn't find anything. So is _vscprintf a MSVC++ function only? If it is, is there an alternative way to get number of characters needed. If it isn't MSVC++ only what should I do to use it?
Advertisement
Quote:Original post by CTar
My problem is that Dev-C++ says that _vsprintf is undefined.


Well i've never seen _vsprintf in VC either because it just vsprintf (with-out underscores) in both its standard C (C89), are sure you didn't mean _vsnprintf.

If so its been standardized in C99 called "vsnprintf" and as Dev-C++ uses mingw which is GCC compiler it supports some of C99 and available as C++ extensions, in the case of Dev-C++ its simply vsnprintf (with-out underscores).

Quote:Original post by CTar
So is _vscprintf a MSVC++ function only?


Yes its not in any standard as far as i'm aware, you can tell has it a leading underscore, thats not typical standard library naming conventions (except for internal use).
Microsoft added an underscore in front of some POSIX functions they do provide. Take it out if compiling with GCC. So you'll be looking for vsnprintf. I don't believe I've ever heard of vscprintf.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny
I don't believe I've ever heard of vscprintf.


Its a visual C++ extension, checked it up on MSDN, VC only.
Thanks for the replies, the _vscprintf fnction has the following signature:

int _vscprintf(const char* format,va_list arg_ptr);

It returns the length of the string needed for the first parameter of vsprintf. So you can use it like this:

//FormatString assigned beforeva_list ArgPtr;va_start(ArgPtr,FormatStr);char* FinalString = new char[_vscprintf(FormatStr,ArgPtr)+1];vsprintf(FinalString,FormatString,ArgPtr);va_end(ArgPtr);


So is there a way to do this in standard C++ or do I have to let FinalString be of a predetermined size(512 probably)
The easiest portable way is to set a reasonable buffer size (say 512 chars) and just use vsnprintf (note the n! you want the version that limits the number of characters written so that you don't buffer overflow).

If you want to have dynamic allocation and be sure that any format string fits, you can use the GNU specific function vasprintf, or try to use the return value from vsnprintf.

When the buffer is too small, vsnprintf returns (according to the standard) the number of characters (not including the terminating null char) that *would* have been produced if the buffer had been big enough. Problem is, many implementations of vsnprintf don't follow the standard, but return -1 (VC's _vsnprintf does that) or the passed in size of the buffer (say 512), or even something completely different - in which case you don't know how big a buffer you'd've needed!

Both ways have their caveats: asprintf only works with the GNU C library, and many vsnprintf implementations don't return correct values when the buffer is too small (hrm.. VC's for example). I guess it would work to test with #ifdef whether you're compiling on VC or gcc and select between two different implementations, something like this:

// Needed to enable asprintf (which is a GNU extension)// Must appear before including stdio.h#ifdef __GNUC__#define _GNU_SOURCE#endif#include <stdio.h>int my_vsprintf(char **retp, const char *format, va_list ap){#if defined(__GNUC__)    return vasprintf(retp, format, ap);#elif defined(_MSC_VER)    // _vscprintf version, saving the newly allocated pointer in *retp    // Make sure to allocate the pointer with malloc(), and free it with free(), since that's what asprintf does (can't delete[] malloc'ed pointers)#endif}
Since you're using C++, I would use std::stringstream:
#include <sstream>// ...int i;char c;std::string string;// Put something in these...std::stringstream stringStream;stringStream << i << c << string;std::string finishedString = stringStream.str();
Thanks, I guess I'll use the solution olsner suggested.

BTW I know of stringstream and often use them, but in some cases I prefer to do it like printf.
Quote:Original post by CTar
but in some cases I prefer to do it like printf.


boost::format gives you printf style format strings with C++ I/O streams.

This topic is closed to new replies.

Advertisement