我可以在Microsoft C ++中测量sprintf所需的缓冲区吗?

时间:2010-02-15 15:34:16

标签: c++ c buffer printf

我正在使用Visual Studio 2008编写一个小概念验证控制台程序,我希望它输出彩色文本以便于阅读。为了便于编码,我还想进行快速的printf替换,我可以像这样编写:

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

这很有用,因为我还在某些地方构建并传递字符串,因此我的字符串将能够包含格式信息。

然而,我碰到了wsprintf的墙,因为我找不到一个能让我在将它传递给函数之前找出所需缓冲区大小的函数。当然,我可以分配1MB即可,但这不会很好,如果我找不到更好的方法,我宁愿将其作为备份解决方案。

另外,或者我正在考虑使用std::wstring(我实际上更像是一个C ++经验很少的C人,所以我现在发现普通的char-arrays更容易了),但那不是有类似wsprintf的内容,您可以在其中构建一个字符串,其中包含值。

所以...我该怎么办?

6 个答案:

答案 0 :(得分:4)

您的问题标记为C ++,在这种情况下我会说std :: wstringstream是要走的路。例如:

#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.

    // ...
}

答案 1 :(得分:3)

我会选择C ++字符串流。它不像sprintf那么紧凑,但它会为你提供你想要的功能。

答案 2 :(得分:3)

你想要_snwprintf。该函数采用缓冲区大小,如果缓冲区不够大,只需将缓冲区大小加倍,然后重试。为了避免每次都要进行多次_snwprintf调用,请跟踪上次使用的缓冲区大小,并始终从那里开始。你会在这里和那里做一些多余的电话,你会不时地浪费一些公羊,但是效果很好,不能超过任何东西。

答案 3 :(得分:2)

如果你能负担得起使用提升,你可以考虑boost::format。它会为您提供std::string的灵活性,以及​​sprintf的格式化功能。它与C风格完全不同,但也相当容易使用。这是一个example

答案 4 :(得分:1)

_scprintf, _scprintf_l, _scwprintf, _scwprintf_l

此函数将返回格式化字符串中的字符数。

答案 5 :(得分:0)

如果您计划在对象之间传递字符串,则使用std::wstring似乎是一个很好的解决方案 - 它处理大小并且有一个很好的c_str方法,可以为您提供宽字符数组。

额外的好处是你可以通过引用而不是指针传递它。

当您需要实际字符串时,只需使用c_str方法:

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