【问题标题】:What is mbstate_t and why to reset it?什么是 mbstate_t 以及为什么要重置它?
【发布时间】:2022-01-22 17:31:43
【问题描述】:

你能解释一下mbstate_t到底是什么吗?我已经阅读了cppreference description,但我仍然不明白它的用途。我所理解的是mbstate_t 是一些静态结构,对于有限的一组函数(如mbtowc()wctomb() 等)可见,但我仍然对如何使用它感到困惑。我可以在 cppreference 示例中看到,在调用某些函数之前应该重置这个结构。假设,我想计算这样一个多语言字符串中的字符:

std::string str = "Hello! Привет!";

显然,str.size() 不能在这个例子中使用,因为它只是返回字符串中的字节数。但是这样的事情就可以了:

std::locale::global(std::locale("")); // Linux, UTF-8
std::string str = "Hello! Привет!";
std::string::size_type stringSize = str.size();
std::string::size_type nCharacters = 0;
std::string::size_type nextByte = 0;
std::string::size_type nBytesRead = 0;
std::mbtowc(nullptr, 0, 0); // What does it do, and why is it needed?
while (
    (nBytesRead = std::mbtowc(nullptr, &str[nextByte], stringSize - nextByte))
    != 0)
{
    ++nCharacters;
    nextByte += nBytesRead;
}
std::cout << nCharacters << '\n';

根据 cppreference 示例,在进入 while 循环之前,mbstate_t 结构应该通过调用 mbtowc() 来重置,所有参数都为零。这样做的目的是什么?

【问题讨论】:

    标签: c++ unicode locale wchar-t wstring


    【解决方案1】:

    mbtowc 的界面有点疯狂。我猜这是一个历史错误。

    您不需要向它传递一个完整的字符串,但可以传递一个以不完整的多字节字符结尾的缓冲区(可能是一个网络包)。然后在下一次调用中传递字符的其余部分。

    所以mbtowc 必须在调用之间存储其当前(可能是部分)转换状态。可能作为静态变量。

    std::mbtowc(nullptr, 0, 0); 的调用将清除此内部状态,因此它已准备好接收新字符串。

    您可能想改用mbrtowc 并提供非隐藏的mbstate_t 作为额外参数。

    https://en.cppreference.com/w/cpp/string/multibyte/mbrtowc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-21
      • 2015-07-04
      • 2011-10-22
      • 2014-06-01
      • 1970-01-01
      • 2021-05-11
      • 2020-10-25
      • 1970-01-01
      相关资源
      最近更新 更多