这段代码在VS2013下编译好了:
std::string Unicode::utf16_to_utf8(std::u16string utf16_string)
{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.to_bytes(utf16_string);
}
Run Code Online (Sandbox Code Playgroud)
现在使用VS2015我得到:
1>unicode.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: static class std::locale::id std::codecvt<char16_t,char,struct _Mbstatet>::id" (__imp_?id@?$codecvt@_SDU_Mbstatet@@@std@@2V0locale@2@A)
Run Code Online (Sandbox Code Playgroud) 我正在建立一个允许我以各种编码方式获取字符串的API,包括utf8,utf16,utf32和wchar_t(根据操作系统可能是utf32或utf16).
新的C++标准已推出了新的类型char16_t,并char32_t没有这个的sizeof歧义,应在今后的使用,所以我想支持他们为好,但问题是,它们会干扰正常的uint16_t,uint32_t,wchar_t类型不允许超载,因为他们可以指同一类型?
class some_class {
public:
void set(std::string); // utf8 string
void set(std::wstring); // wchar string utf16 or utf32 according
// to sizeof(wchar_t)
void set(std::basic_string<uint16_t>)
// wchar independent utf16 string
void set(std::basic_string<uint32_t>);
// wchar independent utf32 string
#ifdef HAVE_NEW_UNICODE_CHARRECTERS
void set(std::basic_string<char16_t>)
// new standard utf16 string
void set(std::basic_string<char32_t>);
// new standard utf32 string
#endif
};
Run Code Online (Sandbox Code Playgroud)
所以我可以写:
foo.set(U"Some utf32 String");
foo.set(u"Some utf16 string");
Run Code Online (Sandbox Code Playgroud)什么是typedef的std::basic_string<char16_t>和std::basic_string<char32_t>今天有:
typedef …Run Code Online (Sandbox Code Playgroud)C++ 11引入char16_t并char32_t便于使用UTF-16和UTF-32编码的文本字符串.但是该<iostream>库仍然只支持wchar_t为多字节I/O 定义的实现.
为什么支持char16_t和char32_t未添加到<iostream>库中以补充wchar_t支持?
我有一个简单的问题:是否有办法strlen()在零端接char16_t数组中进行类似字符计数?
这也char32_t和任何有关intXX_t.规范指出:
2.14.3.2:
包含单个c-char的char16_t文字的值等于其ISO 10646代码点值,前提是代码点可用单个16位代码单元表示.
5.3.3.1:
[..]特别是[...] sizeof(char16_t),sizeof(char32_t)和sizeof(wchar_t)是实现定义的
intXX_t除了评论它们是"可选的"(18.4.1)之外,我看不出有关类型的任何信息.
如果不char16_t保证是2个字节,那么它是否保证是16位(即使在1个字节的架构上!= 8位)?
最近我将Windows应用程序移植到Linux时出现问题,因为wchar_t这些平台之间存在大小差异.我试图使用编译器开关,但打印这些字符时出现问题(我认为GCC wcout认为所有wchar_t都是32位).
所以,我的问题是:有一个很好的方法(w)cout char16_t吗?我问,因为它不起作用,我被迫将其投射到wchar_t:
cout << (wchar_t) c;
Run Code Online (Sandbox Code Playgroud)
这似乎不是一个大问题,但它让我烦恼.
在C11,对于便携式宽字符类型的支持char16_t和char32_t被加入分别为UTF-16和UTF-32.
但是,在技术报告中,没有提到这两种类型的字节顺序.
例如,使用以下代码gcc-4.8.4编译时,我的x86_64计算机上的以下代码段-std=c11:
#include <stdio.h>
#include <uchar.h>
char16_t utf16_str[] = u"??"; // U+5341 U+516D
unsigned char *chars = (unsigned char *) utf16_str;
printf("Bytes: %X %X %X %X\n", chars[0], chars[1], chars[2], chars[3]);
Run Code Online (Sandbox Code Playgroud)
会产生
Bytes: 41 53 6D 51
Run Code Online (Sandbox Code Playgroud)
这意味着它是小端的.
但这种行为平台/实现是否依赖:它是否始终遵循平台的字节序,或者某些实现是否可以选择始终实现char16_t并char32_t使用big-endian?
以下代码按预期工作。源代码,文件“file.txt”和“out.txt”都是用utf8编码的。但是,当我改变它不工作wchar_t,以char16_t在第一线main()。我已经尝试过 gcc5.4 和 clang8.0 与-std=c++11. 我的目标是替换wchar_t为char16_t, aswchar_t在 RAM 中占用两倍的空间。我认为这两种类型在 c++11 和更高版本的标准中同样得到很好的支持。我在这里想念什么?
#include<iostream>
#include<fstream>
#include<locale>
#include<codecvt>
#include<string>
int main(){
typedef wchar_t my_char;
std::locale::global(std::locale("en_US.UTF-8"));
std::ofstream out("file.txt");
out << "123?????abc" << std::endl;
out.close();
std::basic_ifstream<my_char> win("file.txt");
std::basic_string<my_char> wstr;
win >> wstr;
win.close();
std::ifstream in("file.txt");
std::string str;
in >> str;
in.close();
std::wstring_convert<std::codecvt_utf8<my_char>, my_char> my_char_conv;
std::basic_string<my_char> conv = my_char_conv.from_bytes(str);
std::cout << (wstr == conv ? "true" : "false") << std::endl;
std::basic_ofstream<my_char> wout("out.txt"); …Run Code Online (Sandbox Code Playgroud)