【问题标题】:std::string::size() strange behaviourstd::string::size() 奇怪的行为
【发布时间】:2016-08-20 12:40:31
【问题描述】:

我相信输出与 UTF 有关,但我不知道如何。 请有人解释一下吗?

#include <iostream>
#include <cstdint>
#include <iomanip>
#include <string>

int main()
{

    std::cout << "sizeof(char) = " << sizeof(char) << std::endl;
    std::cout << "sizeof(std::string::value_type) = " << sizeof(std::string::value_type) << std::endl;

    std::string _s1 ("abcde");
    std::cout << "s1 = " << _s1 << ", _s1.size() = " << _s1.size() << std::endl;


    std::string _s2 ("abcdé");
    std::cout << "s2 = " << _s2 << ", _s2.size() = " << _s2.size() << std::endl;

    return 0;
}

输出是:

sizeof(char) = 1    
sizeof(std::string::value_type) = 1    
s1 = abcde, _s1.size() = 5    
s2 = abcdé, _s2.size() = 6

g++ --version 打印 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.1) 5.4.0 20160609

QTCreator 编译如下:

g++ -c -m32 -pipe -g -std=c++0x -Wall -W -fPIC  -I../strsize -I. -I../../Qt/5.5/gcc/mkspecs/linux-g++-32 -o main.o ../strsize/main.cpp
g++ -m32 -Wl,-rpath,/home/rodrigo/Qt/5.5/gcc -o strsize main.o

非常感谢!

【问题讨论】:

  • 尝试打印sizeof('é'),看看你会得到什么。
  • 感谢您的宝贵时间。我添加了这两行:std::cout &lt;&lt; "sizeof('é') = " &lt;&lt; sizeof('é') &lt;&lt; std::endl;std::cout &lt;&lt; "sizeof(\"é\") = " &lt;&lt; sizeof("é") &lt;&lt; std::endl; 输出为:sizeof('é') = 4sizeof("é") = 3
  • @canellas sizeof('é') 可能将char 提升为int,这可以解释为什么它的大小是4。字符串文字"é" 等同于const char[],所以@ 987654338@ 是 3,因为 é 在 UTF-8 (0xC3 0xA9) 中使用 2 chars 编码,后跟空终止符。
  • 感谢您的 cmets!我还是有点迷茫...std::cout 怎么知道abcdé 的位置 5 e 6 中的字节必须在打印之前组合成两个字节的值?
  • how can std::cout know that the bytes in position 5 e 6 of abcdé must be combined in a two byte value, before printing?:没有。它盲目地输出字符串的 6 个字节,与它们的内容无关。您的 console(即 term/bash 等)设置为 UTF-8 环境并显示适当的字形。见How to set up a clean UTF-8 environment in Linux。

标签: c++ std stdstring


【解决方案1】:

é 在 utf-8 中编码为 2 个字节,0xC3 0xA9。

【讨论】:

    【解决方案2】:

    gccdefault input character set is UTF-8。您的编辑器也可能将文件保存为 UTF-8,因此在您的输入 .cpp 文件中,字符串 abcdé 将有 6 个字节(正如彼得已经回答的那样,LATIN SMALL LETTER E WITH ACUTE 以 UTF-8 编码,有 2 个字节)。 std::string::length 返回字节长度,即。 6. QED

    您应该在十六进制编辑器中打开您的源 .cpp 文件以确认。

    【讨论】:

      【解决方案3】:

      即使在 C++11 中 std::string 也与 UTF-8 无关。在size的description和std::string的length方法中我们可以看到:

      对于 std::string,元素是字节(char 类型的对象),如果使用 UTF-8 等多字节编码,则它们与字符不同。

      因此,您应该使用一些第三方 unicode 兼容库来处理 unicode 字符串。

      如果您继续使用带有 unicode 字符串的非 unicode 字符串类,您可能会面临很多其他问题。例如,当您尝试比较外观相同的 combining character 和 precomposed character 时,您会得到一个虚假的结果。

      【讨论】:

      • 这很好地解释了它。 UTF8 完全代表了这一点,这是一个无关紧要的巧合。
      猜你喜欢
      • 2016-09-02
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      相关资源
      最近更新 更多