【问题标题】:std::get_time and other locale functionality not working correctly on Windowsstd::get_time 和其他语言环境功能在 Windows 上无法正常工作
【发布时间】:2011-10-02 16:02:48
【问题描述】:

在尝试使 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 中糟糕的语言环境支持,还是我可以修复或解决的错误的依赖于实现的假设(输入格式)?

【问题讨论】:

  • Clare:每一个元素:所有元素都只是 0,而不是断言中预期的值。
  • 嗯,是的,我明白你的意思了。在 Visual C++ 2010 Express 中,我也得到了全零 - 使用默认创建的 C++ 控制台应用程序。
  • 那些甚至是 Windows 接受的语言环境的种类和格式吗? Windows 生活在 UTF-16 世界中,所以我怀疑它们是否支持很多 UTF-8 语言环境。
  • Nicol Bolas:请注意,我在UTF_8 定义中作弊并使用了Windows 代码页。特别是对于简单的英语(en_US),这个简单的例子应该可以工作。 istream::imbue 没有失败。我证实了这一点。

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


【解决方案1】:

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

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

【讨论】:

  • hereherethis 似乎建议不同的命名......我很困惑:(
【解决方案2】:

这里暴露的问题不是 - 错误的语言环境名称 - 错误的std::tm

但这恰恰在于%c 格式说明符在Windows 上没有达到预期的效果。通过完整指定格式,这很容易解决。在这种情况下,我使用的是:

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

%Y 部分仍然存在问题(tm_year 仍然为零)...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    相关资源
    最近更新 更多