std :: get_time和其他语言环境功能在Windows上无法正常运行

时间:2011-10-02 16:02:48

标签: c++ visual-c++ locale c++11 iomanip

在我尝试使libc ++及其测试在Windows上运行时,我遇到了一个我似乎无法解决的问题。以下代码取自libc ++测试代码,并传递给Mac(也可能是FreeBSD),但不能传递给MinGW-w64和MSVC 2010 SP1。

#include <iomanip>
#include <iostream>
#include <cassert>

template <class CharT>
struct testbuf
    : public std::basic_streambuf<CharT>
{
    typedef std::basic_string<CharT> string_type;
    typedef std::basic_streambuf<CharT> base;
private:
    string_type str_;
public:

    testbuf() {}
    testbuf(const string_type& str)
        : str_(str)
    {
        base::setg(const_cast<CharT*>(str_.data()),
                   const_cast<CharT*>(str_.data()),
                   const_cast<CharT*>(str_.data()) + str_.size());
    }
};
#if _WIN32
#define LOCALE_en_US_UTF_8 "English_USA.1252"
#else
#define LOCALE_en_US_UTF_8 "en_US.UTF-8"
#endif
int main()
{
    testbuf<char> sb("  Sat Dec 31 23:55:59 2061");
    std::istream is(&sb);
    is.imbue(std::locale(LOCALE_en_US_UTF_8));
    std::tm t = {0};
    is >> std::get_time(&t, "%c");
    std::cout << t.tm_sec << "\n";
    std::cout << t.tm_min << "\n";
    std::cout << t.tm_hour << "\n";
    std::cout << t.tm_mday << "\n";
    std::cout << t.tm_mon << "\n";
    std::cout << t.tm_year << "\n";
    std::cout << t.tm_wday << "\n";
    assert(t.tm_sec == 59);
    assert(t.tm_min == 55);
    assert(t.tm_hour == 23);
    assert(t.tm_mday == 31);
    assert(t.tm_mon == 11);
    assert(t.tm_year == 161);
    assert(t.tm_wday == 6);
}

Mac / FreeBSD的测试通过,但Windows的不同元素都是0。这适用于MinGW-w64 + libc ++和MSVC10 + Microsoft的STL。

这在Windows中是否只是糟糕的语言环境支持,或者是否存在错误的依赖于实现的假设(输入格式),我可以修复或解决这个问题?

2 个答案:

答案 0 :(得分:0)

我不相信你有正确的语言环境字符串。它们似乎记录得非常糟糕,尽管它看起来像一个好的列表here

也许是“american_us.1252”? (当然,这些字符串都是实现定义的。)

答案 1 :(得分:0)

这里暴露的问题不是   - 错误的区域设置名称   - 错误的std::tm

但完全在于%c格式说明符不能在Windows上执行预期的事实。通过完整指定格式,这很容易修复。在这种情况下,我使用的是:

"%a %b %d %H" ":" "%M" ":" "%S %Y"

%Y部分仍有问题(tm_year仍为零)...