std::string与std::u16string(或u32string)的区别



在问这个问题之前,我参考了下面的帖子:

std::string, wstring, u16/32string澄清
Std::u16string, Std::u32string, Std::string, length(), size(),代码点和字符

但是他们不知道我的问题。请看下面的简单代码:

#include<iostream>
#include<string>
using namespace std;
int main ()
{
  char16_t x[] = { 'a', 'b', 'c', 0 };
  u16string arr = x;
  cout << "arr.length = " << arr.length() << endl;
  for(auto i : arr)
    cout << i << "n";
}

输出为:

arr.length = 3  // a + b + c
97
98
99

考虑到std::u16stringchar16_t而不是char组成,那么输出应该是:

arr.length = 2  // ab + c()
<combining 'a' and 'b'>
99

请原谅我的新手问题。我的要求是弄清楚新的c++ 11字符串的概念。

编辑:

从@Jonathan的回答中,我找到了问题的漏洞。我的观点是如何初始化char16_t,使arr的长度变成2(即ab, c)。
仅供参考,下面给出了不同的结果:

  char x[] = { 'a', 'b', 'c', 0 };
  u16string arr = (char16_t*)x;  // probably undefined behavior
输出:

arr.length = 3
25185
99
32767

不,您已经创建了一个包含四个元素的数组,第一个元素是'a'转换为char16_t,第二个元素是'b'转换为char16_t等。

然后从该数组(转换为指针)创建一个u16string,它读取每个元素直到空终止符。

当你这样做的时候:

char16_t x[] = { 'a', 'b', 'c', 0 };

类似于这样做(不考虑端序):

char x[] = { '', 'a', '', 'b', '', 'c', '', '' };

每个字符占用两个字节内存。

因此,当您要求u16string的长度时,每个两个字节被计数为一个字符。毕竟,它们是两个字节(16位)的字符。

编辑:

您的附加问题是创建字符串而不使用空终止符。

试试这个:

char x[] = { 'a', 'b', 'c', 0 , 0, 0};
u16string arr = (char16_t*)x;

现在第一个字符是{'a', 'b'},第二个字符是{'c', 0},你也有一个空结束符{0, 0}

输出不应该是:

加勒比海盗。长度= 2
//ab + c()99

x的元素是char16_t,无论您是否为初始化提供char字面值:

#include<iostream>
int main () {
    char16_t x[] = { 'a', 'b', 'c', 0 };
    std::cout << sizeof(x[0]) << std::endl;
}
输出:

2 

生活例子

附录指问题的编辑

我并不建议将终止符从字符串中强制转换出来。;)

#include<iostream>
#include<string>
int main () {
    char x[] = { 'a', 'b', 'c', 0, 0, 0, 0, 0};
    std::wstring   ws   = reinterpret_cast<wchar_t*>(x);
    std::u16string u16s = reinterpret_cast<char16_t*>(x);
    std::cout << "sizeof(wchar_t):  "       << sizeof(wchar_t)
              << "twide string length: "   << ws.length()   
              << std::endl;
    std::cout << "sizeof(char16_t): "       << sizeof(char16_t)
               << "tu16string length:  "   << u16s.length()   
               << std::endl;
}

生活例子

输出(用g++编译)

sizeof(wchar_t):  4 wide string length: 1
sizeof(char16_t): 2 u16string length:   2

不出所料,不是吗

c++支持以下从8位整数生成16位整数的方法:

char16_t ab = (static_cast<unsigned char>('a') << 8) | 'b';
// (Note: cast to unsigned meant to prevent overflows)

最新更新