如何打印混合 ASCII 字符和 Unicode 的字符串的每个字符
how to print each character of strings that mix ascii character with unicode?
例如,我想创建一些打字机效果,因此需要打印这样的字符串:
#include <string>
int main(){
std::string st1="ab》cd《ef";
for(int i=0;i<st1.size();i++){
std::string st2=st1.substr(0,i).c_str();
printf("%sn",st2.c_str());
}
return 0;
}
但输出是
a
ab
ab?
ab?
ab》
ab》c
ab》cd
ab》cd?
ab》cd?
ab》cd《
ab》cd《e
而不是:
a
ab
ab》
ab》c
ab》cd
ab》cd《
ab》cd《e
如何知道即将到来的字符是 Unicode?
类似的问题,打印每个字符也有问题:
#include <string>
int main(){
std::string st1="ab》cd《ef";
for(int i=0;i<st1.size();i++){
std::string st2=st1.substr(i,1).c_str();
printf("%sn",st2.c_str());
}
return 0;
}
输出为:
a
b
?
?
?
c
d
?
?
?
e
f
不:
a
b
》
c
d
《
e
f
我认为问题是编码。您的字符串可能采用具有可变大小字符的UTF-8
编码。这意味着您不能一次迭代一个char
,因为某些字符的宽度char
多
事实上,在 unicode 中,您一次只能使用 UTF-32
编码可靠地迭代一个固定字符。
因此,您可以做的是使用像 ICU 这样的UTF
库来转换 vetween UTF-8
和 UTF-32
.
如果你有C++11
那么这里有一些工具可以帮助你,主要是std::u32string
能够容纳UTF-32
编码字符串的工具:
#include <string>
#include <iostream>
#include <unicode/ucnv.h>
#include <unicode/uchar.h>
#include <unicode/utypes.h>
// convert from UTF-32 to UTF-8
std::string to_utf8(std::u32string s)
{
UErrorCode status = U_ZERO_ERROR;
char target[1024];
int32_t len = ucnv_convert(
"UTF-8", "UTF-32"
, target, sizeof(target)
, (const char*)s.data(), s.size() * sizeof(char32_t)
, &status);
return std::string(target, len);
}
// convert from UTF-8 to UTF-32
std::u32string to_utf32(const std::string& utf8)
{
UErrorCode status = U_ZERO_ERROR;
char32_t target[256];
int32_t len = ucnv_convert(
"UTF-32", "UTF-8"
, (char*)target, sizeof(target)
, utf8.data(), utf8.size()
, &status);
return std::u32string(target, (len / sizeof(char32_t)));
}
int main()
{
// UTF-8 input (needs UTF-8 editor)
std::string utf8 = "ab》cd《ef"; // UTF-8
// convert to UTF-32
std::u32string utf32 = to_utf32(utf8);
// Now it is safe to use string indexing
// But i is for length so starting from 1
for(std::size_t i = 1; i < utf32.size(); ++i)
{
// convert back to to UTF-8 for output
// NOTE: i + 1 to include the BOM
std::cout << to_utf8(utf32.substr(0, i + 1)) << 'n';
}
}
输出:
a
ab
ab》
ab》c
ab》cd
ab》cd《
ab》cd《e
ab》cd《ef
注意:
ICU 库在其转换为 Unicode 的字符串的开头添加一个BOM
(字节顺序标记)。因此,您需要处理UTF-32
字符串的第一个字符是BOM
的事实。这就是为什么子字符串使用 i + 1
作为其长度参数以包含 BOM
的原因。
您的C++代码只是将八位字节回显到您的终端,并且您的终端显示器正在将以默认字符集编码的八位字节转换为 unicode 字符。
根据您的示例,您的终端显示器似乎使用 UTF-8。将 UTF-8 编码字符转换为 unicode 的规则相当明确(Google 是你的朋友),所以你所要做的就是检查 UTF-8 序列的第一个字符,以确定有多少个八位字节组成下一个 unicode 字符。
相关文章:
- 如何存储 unicode 字符并将其输出到文件?
- C++:打印 Unicode 字符
- 在 Windows 中使用 boost::p rogram_options 从命令行参数读取 Unicode 字符
- 获取Unicode字符C++的十进制值
- 用wchar_t处理 unicode 字符好吗?它不会引起任何问题吗?
- C++如何通过忽略每行的第一个字符来读取 unicode 文件
- C++:如何将 unicode 字符打印到文本文件
- 动态计算 unicode 字符
- C Unicode UTF-8解码字符的问题
- 如何替换/忽略 C stdio.h getline() 中的无效 Unicode/UTF8 字符
- 无法使用 Unicode 特殊字符设置窗口文本
- 如何将整数转换为 unicode 字符
- C++20 中的严格别名规则是否允许标准 c++ unicode 字符和下划线类型之间"reinterpret
- MessageBox打印来自TCHAR缓冲区的额外Unicode字符
- 如何将小数NCR转换为Unicode字符(C )
- SQLGetPrivateProfileString 错误地读取 Unicode 字符
- 将 Unicode 字符/字符串写入文件
- 将 Unicode 字符存储在.txt文件中的新行中
- 是否有返回字符UNICODE值的函数?(C++)
- 将字符串宏/常量转换为宽字符/Unicode