首页 文章

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

提问于
浏览
1

我在此之前询问了以下帖子:

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字符串的概念 .

Edit

从@ 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 回答

  • 1

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

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

  • 2

    当你这样做时:

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

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

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

    每个角色在内存中占据 two bytes .

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

    EDIT:

    您的其他问题是创建一个字符串 without 一个空终止符 .

    试试这个:

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

    现在第一个字符是 {'a', 'b'} ,第二个字符是 {'c', 0} ,你还有一个空终止符 {0, 0} .

  • 0

    输出不应该是: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

    Addendum ,指的是问题的编辑

    我并不建议远离琴弦 . ;)

    #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
    

    不出所料,不是吗 .

  • 4

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

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

相关问题