std::string的format一种实现

  • 由于std标准库的string没有实现类似CString的Format函数,使得我们有时候不得不使用istream、ostream来格式化字符串,然而这些类使用起来又复杂繁琐。在Windows下编程时我们还可以使用CString的Format函数,但是这里也可能会涉及到字符类型的转换等问题。而且使用CString的Format函数就意味着代码无法做到跨平台。
  • 于是我在VS下敲下了如下代码:
#include <iostream>
#include <string>
#include <stdarg.h>

int std_string_format(std::string & str, const char * format, ...) {
    std::string tmp;

    va_list marker;
    va_start(marker, format);

    size_t num = _vscprintf(format, marker);

    if (num >= tmp.capacity())
        tmp.reserve(num + 1);

    vsprintf_s((char *)tmp.data(), tmp.capacity(), format, marker);

    va_end(marker);

    str = tmp.c_str();
    return str.size();
}

int std_wstring_format(std::wstring & str, const wchar_t * format, ...) {
    std::wstring tmp;

    va_list marker;
    va_start(marker, format);

    size_t num = _vscwprintf(format, marker);

    if (num >= tmp.capacity())
        tmp.reserve(num + 1);

    vswprintf_s((wchar_t *)tmp.data(), tmp.capacity(), format, marker);

    va_end(marker);

    str = tmp.c_str();
    return str.size();
}

int main()
{
    std::string std_str;
    int len = std_string_format(std_str, "hello %s!", "world");
    std::cout << "std_str=" << std_str << ", len=" << len << std::endl;

    std::wcout.imbue(std::locale("chs"));

    std::wstring std_wstr;
    len = std_wstring_format(std_wstr, L"你好 %s!", L"世界");
    std::wcout << L"std_wstr=" << std_wstr << L", len=" << len << std::endl;

    system("pause");
}
  • 在VS下编译运行结果:
std_str=hello world!, len=12
std_wstr=你好 世界!, len=6
  • 可是这段代码在wandbox下编译不过,原来是因为_vscprintf和vsprintf_s是微软提供的函数。于是,我在wandbox下修改了一下代码:
#include <iostream>
#include <string>
#include <stdarg.h>

int format_num(const char *format, ...)
{
    va_list args;
    va_start(args, format);
    int num = vsnprintf(0, 0, format, args);
    va_end(args);
    return num;
}

int format_num(const wchar_t *format, ...)
{
    va_list args;
    va_start(args, format);
    int num = vswprintf(0, 0, format, args);
    va_end(args);
    return num;
}

int std_string_format(std::string & str, const char * format, ...) {
    std::string tmp;

    va_list marker;
    va_start(marker, format);

    size_t num = format_num(format, marker);

    if (num >= tmp.capacity())
        tmp.reserve(num + 1);

    vsnprintf((char *)tmp.data(), tmp.capacity(), format, marker);

    va_end(marker);

    str = tmp.c_str();
    return str.size();
}

int std_wstring_format(std::wstring & str, const wchar_t * format, ...) {
    std::wstring tmp;

    va_list marker;
    va_start(marker, format);

    size_t num = format_num(format, marker);

    if (num >= tmp.capacity())
        tmp.reserve(num + 1);

    vswprintf((wchar_t *)tmp.data(), tmp.capacity(), format, marker);

    va_end(marker);

    str = tmp.c_str();
    return str.size();
}

int main()
{
    std::string std_str;
    int len = std_string_format(std_str, "hello %s!", "world");
    std::cout << "std_str=" << std_str << ", len=" << len << std::endl;

    std::wcout.imbue(std::locale("chs"));

    std::wstring std_str_ch;
    len = std_wstring_format(std_str_ch, L"你好 %s!", L"世界");
    std::wcout << L"std_str_ch=" << std_str_ch << L", len=" << len << std::endl;
}
  • 其运行结果如下:
std_str=hello world!, len=12
std_str_ch=你好 世界!, len=6
  • wandbox的中文设置有问题,运行结果是在Windows下跑出来的,应该是OK了。
阅读 638

推荐阅读

学技术简单记,吴尼玛带你记笔记。

0 人关注
40 篇文章
专栏主页