std :: string和std :: u16string(或u32string)之间的区别

时间:2014-07-25 09:07:00

标签: c++ string c++11 output

我在此之前提到了以下帖子:

std::string, wstring, u16/32string clarification
std::u16string, std::u32string, std::string, length(), size(), codepoints and characters

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

#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(\0)
<combining 'a' and 'b'>
99

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

修改

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

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

输出:

arr.length = 3
25185
99
32767

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

当你这样做时:

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

类似于这样做(字节顺序不能承受):

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

每个角色在内存中占用 两个字节

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

修改

您的其他问题是创建字符串 ,不带 空终结符。

试试这个:

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

现在第一个字符为{'a', 'b'},第二个字符为{'c', 0},您还有一个空终结符{0, 0}

答案 2 :(得分:1)

  

输出不应该是:

     

arr.length = 2
  // ab + c(\ 0)   99

没有。 x的元素是char16_t,无论您为初始化提供char文字,都是如此:

#include<iostream>

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

输出:

2 

Live example

附录指的是问题的编辑

我并不建议远离字符串。 ;)

#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;
}

Live example

输出(用g ++编译)

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

正如所料,不是。

答案 3 :(得分:0)

C ++支持以下方法从8位整数构建16位整数:

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