Sign in to follow this  
CTar

_vscprintf?

Recommended Posts

CTar    1134
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?

Share this post


Link to post
Share on other sites
snk_kid    1312
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).

Share this post


Link to post
Share on other sites
Fruny    1658
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.

Share this post


Link to post
Share on other sites
snk_kid    1312
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.

Share this post


Link to post
Share on other sites
CTar    1134
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 before

va_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)

Share this post


Link to post
Share on other sites
olsner    132
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
}

Share this post


Link to post
Share on other sites
Roboguy    794
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();

Share this post


Link to post
Share on other sites
CTar    1134
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this