[英]How to initialize a const char* and/or const std::string in C++ with a sequence of UTF-8 character?
[英]How to remove the last character of a UTF-8 string in C++?
文本存储在std::string
。
如果文本是8位ASCII,那么它很容易:
text.pop_back();
但如果它是UTF-8文本怎么办?
据我所知,标准库中没有与UTF-8相关的函数可以使用。
如果你打算使用UTF-8
你真的需要一个UTF-8库 。 但是对于这项任务,我认为这样的事情就足够了:
void pop_back_utf8(std::string& utf8)
{
if(utf8.empty())
return;
auto cp = utf8.data() + utf8.size();
while(--cp >= utf8.data() && ((*cp & 0b10000000) && !(*cp & 0b01000000))) {}
if(cp >= utf8.data())
utf8.resize(cp - utf8.data());
}
int main()
{
std::string s = "κόσμε";
while(!s.empty())
{
std::cout << s << '\n';
pop_back_utf8(s);
}
}
输出:
κόσμε
κόσμ
κόσ
κό
κ
它依赖于UTF-8编码有一个起始字节后跟几个连续字节的事实。 可以使用提供的按位运算符检测那些连续字节 。
你可以做的是弹出字符,直到你到达代码点的前导字节。 UTF8中代码点的前导字节是模式0xxxxxxx
或11xxxxxx
,所有非前导字节的形式为10xxxxxx
。 这意味着您可以检查第一个和第二个位以确定是否有前导字节。
bool is_leading_utf8_byte(char c) {
auto first_bit_set = (c & 0x80) != 0;
auto second_bit_set = (c & 0X40) != 0;
return !first_bit_set || second_bit_set;
}
void pop_utf8(std::string& x) {
while (!is_leading_utf8_byte(x.back()))
x.pop_back();
x.pop_back();
}
这当然不会进行错误检查,并假设您的字符串是有效的utf-8。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.