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了。
相關文章
相關標籤/搜索