C++,linux,如何有效地从字符串中弹出非拉丁字符pop_back()
C++, linux, how to pop_back() efficiently a non latin1 char from a string
我对string
操作有问题,首先考虑这些string
s:
string s1 = "Graveworm";
string s2 = "Motörhead"; //the best of the best, just to say...
正如你所看到的,它们每个都有9个char
,是的。。但不是…因为当我pop_back()
一个像"é"这样重音的字母时,我必须pop_back()
两个char
秒。
所以现在,有一种方法可以知道我有多少char
(s)到pop_back()
,记住s1
和s2
写在代码中。
注意:在写这个问题的时候,我想到了一个可能的方法:获取字符串的大小,只要大小没有减少一个,就逐个删除char;嗯,我试过这个:
if(s->size()>0){
int size = s->size();
for(i=size; i > size-1 ;i--){
s->pop_back();
}
未按预期工作
特别是在现代Linux上,大多数(所有?)文本和代码编辑器将"Motörhead"
保存在文件中,引号之间有10个字节。在源代码文件上尝试hexdump
,您会看到类似的内容
00000050 32 20 3d 20 22 4d 6f 74 c3 b6 72 68 65 61 64 22 |2 = "Mot..rhead"|
如果您使用u8"Motörhead"
,您可以使用C++11以可移植的方式实现此行为
至于找出每个多字节字符中有多少字节,这几乎没有必要,但如果你真的需要,std::mblen、std::mbrlen和相关函数可以帮助你。
大多数Linux发行版对非ASCII字符使用UTF-8编码。UTF-8的特性是,所有非初始字节都有一个10xxxxxx
的位模式,因此可以弹出整个UTF-8字符的一种方式如下:
// Note: How this gets compiled depends on your compiler's input character set.
// For GCC, see the -finput-charset and -fexec-charset compiler options.
std::string s = "Motörhead";
while (s.size() > 0)
{
char c = s.back();
s.pop_back();
// If we found an initial character, we're done
if ((c & 0xC0) != 0x80)
break;
}
这是通过弹出字符来实现的,直到我们找到一个初始字符(具有0xxxxxxx
或11xxxxxx
的初始位模式的字符)。它还有一个安全网,可以在您拥有的字符串格式错误且实际上不是有效的UTF-8的情况下拯救和避免Undefined Behavior。
不过,请记住,此代码对其目标环境进行了假设。如果在任何非UTF-8环境中运行此代码,则需要确保在使用此代码之前将字符串转换为UTF-8,并在输出(例如打印到控制台)之前将其转换回目标环境的编码。如果你不能做到这一点,它将以令人惊讶的方式失败(通常是用某种mojibake)。
如果您的编码是UTF-8,您可以利用编码来知道何时到达代码点的第一个字节。当字节值为< 128
(ASCII范围)或介于0xc0
和0xff
之间时,就会出现这种情况。
不幸的是,当你弹出一个代码点时,这只是告诉你。如果您正在考虑组合字符,则一个实际字符可能由多个代码点组成。
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 如何在C++中从字符串中分割字符
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- const_cast<字符 *>(字符* 常量) 不是左值?
- 如何将字符*(字符指针)转换为 PCSZ?
- 将 C++ std::string 中的字符/字符序列替换为另一个字符序列
- 声明多字符字符的警告和错误
- 如何获取字符*(字符数组)的真实长度和总长度
- 我得到以下错误:[警告]多字符字符常量
- C++错误:警告:多字符字符常量/a用于用法
- Char Val = 'ABCD'。使用多字符字符
- 警告多字符字符常量 [-Wmultichar]
- 如何截断前几个字符字符数组 C++
- 比较C++字符* 字符进行解析.OBJ 文件
- 如何将字符串标记复制到字符 */字符数组