开发者

Can I measure the necessary buffer for sprintf in Microsoft C++?

I'm writing a small proof-of-concept console program with Visual Studio 2008 and I wanted it to output colored text for readability. For ease of co开发者_JAVA百科ding I also wanted to make a quick printf-replacement, something where I could write like this:

MyPrintf(L"Some text \1[bright red]goes here\1[default]. %d", 21);

This will be useful because I also build and pass strings around in some places so my strings will be able to contain formatting info.

However I hit a wall against wsprintf because I can't find a function that would allow me to find out the required buffer size before passing it to the function. I could, of course, allocate 1MB just-to-be-sure, but that wouldn't be pretty and I'd rather leave that as a backup solution if I can't find a better way.

Also, alternatively I'm considering using std::wstring (I'm actually more of a C guy with little C++ experience so I find plain-old-char-arrays easier for now), but that doesn't have anything like wsprintf where you could build a string with values replaced in them.

So... what should I do?


Your question is tagged C++, in which case I'd say std::wstringstream is the way to go. Example:

#include <sstream>

void func()
{
    // ...

    std::wstringstream ss;  // the string stream

    // like cout, you can add strings and numbers by operator<<
    ss << L"Some text \1[bright red]goes here\1[default]. " << 21;

    // function takes a C-style const wchar_t* string
    some_c_function(ss.str().c_str()); // convert to std::wstring then const wchar_t*
    // note: lifetime of the returned pointer probably temporary
    // you may need a permanent std::wstring to return the c_str() from
    // if you need it for longer.

    // ...
}


You want _snwprintf. That function takes a buffer size, and if the buffer isn't big enough, just double the size of the buffer and try again. To keep from having to do multiple _snwprintf calls each time, keep track of what the buffer size was that you ended up using last time, and always start there. You'll make a few excess calls here and there, and you'll waste a bit of ram now and then, but it works great, and can't over-run anything.


I'd go for a C++ stringstream. It's not as compact as sprintf but it will give you the functionality you want.


If you can afford using boost, you could consider boost::format. It would give you the flexibility of std::strings, and formatting features of sprintf. It is fairly different from C-style, but is also fairly easy to use. Here's an example.


_scprintf, _scprintf_l, _scwprintf, _scwprintf_l

This functions will return the number of characters in the formatted string.


Using std::wstring seems like a good solution if you plan on passing strings between your objects - it handles the size and has a nice c_str method that will give you the array of wide chars.

The additional benefit is that you can pass it by reference instead of by pointer.

When you need the actuall string just use c_str method:

wprintf(L"string %s recieved!", myWString.c_str());
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜