为什么 std::setw() 将特殊字符视为两个字符?有没有简单又时尚的方法来解决这个问题?
例如:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::left << std::setw(10) << "ok" << "ok" << std::endl;
std::cout << std::left << std::setw(10) << "test.." << "ok again" << std::endl;
std::cout << std::left << std::setw(10) << "®èé" << "fail" << std::endl;
return 0;
}
输出:
ok ok
test.. ok again
®èé fail
这是现场测试:http://ideone.com/q57I0H
它们是两个字符,检查
sizeof("®èé")
的值
编辑:因为评论者对此感到困惑:
std::ostream
使用的“字符”的定义是char
,而不是Unicode所说的字符(可能由可变长度编码中的多个代码单元表示,例如UTF-8)。始终是一字节对应一个字符。您可以使用 std::ostream
输出一系列字节,然后其他使用者可以将其解释为 UTF-8(从文件或管道读取的内容,或显示在终端上),但 ostream
本身一无所知UTF-8,只是将字节从一个地方传输到另一个地方。 ostream
中依赖于字符数的任何成员(例如根据指定宽度确定填充)将仅使用字节。
如果您想要支持 Unicode 的格式,可以使用 std::format
(C++20 起) 和
std::print
(C++23 起)。截至 2023 年 12 月中旬,GCC 尚未处理
std::format
中的多字节字符,因为我还没有实现P2675。碰巧的是,我今天打算做这件事......