1

我在操作上有问题string,首先考虑这些string

string s1 = "Graveworm";
string s2 = "Motörhead"; //the best of the best, just to say...

正如你所看到的,他们每个人都有 9 chars,是的.. 但是没有......因为当我pop_back()有一个像“é”这样的重音字母时,我必须有pop_back()两个chars。

所以现在,有一种方法可以知道我有多少char(s)pop_back(),记住s1s2写在代码中。

注意 :: 在写这个问题时,我想到了一种可能的方法:获取字符串的大小并逐个删除字符,只要大小没有减少一个;好吧,我试过这个:

if(s->size()>0){
         int size = s->size();
         for(i=size; i > size-1 ;i--){
           s->pop_back();
         }

没有按预期工作

4

3 回答 3

3

特别是在现代 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"|

如果您使用,您可以使用 C++11 以可移植的方式实现此行为u8"Motörhead"

至于找出每个多字节字符中有多少字节,很少需要,但如果你真的需要它,std::mblenstd::mbrlen和相关函数可以提供帮助。

于 2013-07-02T21:59:42.907 回答
2

大多数 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;
}

这通过弹出字符来工作,直到我们找到一个初始字符(一个初始位模式为0xxxxxxxor的字符11xxxxxx)。如果您拥有的字符串格式不正确并且实际上不是有效的 UTF-8,它还有一个安全网来拯救和避免未定义的行为。

但请记住,此代码对其目标环境进行了假设。如果您在任何非 UTF-8 环境中运行它,您需要确保在使用此代码之前将您的字符串转换为 UTF-8,并且在输出之前将它们转换回目标环境的编码(例如打印到控制台)。如果您不这样做,它将以令人惊讶的方式失败(通常使用某种类型的mojibake)。

于 2013-07-02T21:59:53.873 回答
2

如果您的编码是 UTF-8,您可以利用编码来了解何时到达代码点的第一个字节。那将是字节值是< 128(ASCII 范围)或介于0xc0and之间的时候0xff

不幸的是,这只会告诉您何时弹出代码点。如果您正在考虑组合字符,则实际字符可能包含多个代码点。

于 2013-07-02T22:00:10.463 回答