什么是 mbstate_t 以及为什么要重置它?

What is mbstate_t and why to reset it?

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

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

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

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() 来重置,所有参数都为零。这样做的目的是什么?

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

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

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

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

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

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