如何在C++20中将表情符号存储在char8_t中并打印出来?

y0u0uwnf  于 2023-03-05  发布在  其他
关注(0)|答案(4)|浏览(91)

我刚刚听说了char8_tchar16_tchar32_t的存在,我正在测试,当我尝试编译下面的代码时,g++抛出了以下错误:

error: use of deleted function ‘std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, char32_t) [with _Traits = char_traits<char>]’
    6 |         std::cout << U'😋' << std::endl;
      |                      ^~~~~
#include <iostream>

int main() {
  char32_t c = U'😋';

  std::cout << c << std::endl;

  return 0;
}

另外,为什么我不能将表情符号放入char8_tchar16_t中?例如,以下代码行无法工作:

char16_t c1 = u'😋';
char8_t c2 = u8'😋';
auto c3 = u'😋';
auto c4 = u8'😋';

据我所知,表情符号是UTF-8字符,因此应该适合char8_t

svmlkihl

svmlkihl1#

表情符号是UTF-8字符
根本就没有“UTF-8字符”这回事。
有Unicode码点,它们可以用UTF-8编码表示,这样每个码点Map到一个或多个UTF-8代码单元的序列:但这意味着大多数码点Map到多个char8_t:也就是字符串,Emojis并不在Map到一个UTF-8代码单元的127个代码点之列。
特别是表情符号可以由 * 多个 * 代码点构建,因此即使使用UTF-32,也不能保证任何表情符号都可以存储在单个char32_t代码点中。
在任何时候,最好把这些东西当作字符串,而不是字符,甚至忘记“字符”的存在。

imzjd6km

imzjd6km2#

当我试图编译下面的代码时,g ++抛出了以下错误:
窄标准流和宽标准流所需的编码取决于实现,也可能取决于最终打印到的终端所需的编码。如果要分别打印到std::coutstd::wcout,则需要将字符转换为charwchar_t类型的正确编码。
另外,为什么我不能将表情符号放入char8_t或char16_t中?例如,以下代码行无法工作:
表情符号是Unicode代码点U +1F60B,在UTF-8和UTF-16编码中都需要多个代码单元。但您尝试形成的是一个 * 字符文本 *,它只包含 * 一个 * 代码单元。
从我的理解来看,表情符号是UTF-8字符[...]
这是没有意义的。UTF-8是一个编码的Unicode码点。这是没有意义的说一个字符"是UTF-8"。这表明你可能有根本的误解如何Unicode和字符/字符串编码一般工作。我建议你阅读一些介绍的主题。

xytpbqjk

xytpbqjk3#

这个管用

#include <iostream>

int main() {
  const char* c = "😋";

  std::cout << c << std::endl;

  return 0;
}

解释。
1.是😋多字节序列,不适合单个char。因此应使用const char*
1.默认的源文件编码是UTF-8,因此Unicode字符只能用于UTF-8编码。对于char32_t,它应该写为U'\x1F60B'
1.对于char8_tchar16_tchar32_t,删除了operator<<(std::basic_ostream)

nukf8bse

nukf8bse4#

#include <iostream>

#ifdef _WIN32 
#include <Windows.h>
#define SET_CONSOLE_UTF8 SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); //Set console output to UTF-8.Visual C++ code on Windows.
#endif // _WIN32 

#if defined(__cpp_char8_t) | defined(__cpp_lib_char8_t)

//Operator <<
std::ostream& operator<<(std::ostream& os, const std::u8string& str)
{
    os << reinterpret_cast<const char*>(str.data());
    return os;
}

//Convert u8string to string.
std::string ToString(const std::u8string& s) {
    return std::string(s.begin(), s.end());
}

std::u8string Tou8String(const std::string& s) {
    return std::u8string(s.begin(), s.end());
}

//const char8_t* literal to string. Operator ""_s
static inline std::string operator"" _s(const char8_t* value, size_t size) {
    static std::string x(reinterpret_cast<const char*>(value), size);
    return x;
}

#endif

using namespace std::string_literals;// operator ""s

int main() {
#ifdef _WIN32
    SET_CONSOLE_UTF8
#endif

        std::u8string u8String = u8"😋😋😋😋"s;// u8string literal.
    std::string str = u8"😋😋😋😋"_s; //Operator "_s". Convert utf8 literal(const char8_t*) to std::string. 

    std::cout << "string              " << str << std::endl; //Using operator << for std::string
    std::cout << "u8string -> string  " << ToString(u8String) << std::endl; //Using function ToString(u8string) -> string
    std::cout << "u8string            " << u8String << std::endl; //Using operator << for std::u8string.
    std::cout << "string -> u8string  " << Tou8String(str) << std::endl; //Using function Tou8String(string) -> u8string
    std::cin.get();
    return 0;
}
string              😋😋😋😋
u8string -> string  😋😋😋😋
u8string            😋😋😋😋
string -> u8string  😋😋😋😋

相关问题