C++ 如何使STL std::string在windows上与unicode一起工作?
在我的公司,我们有一个跨平台(Linux和Windows)库,其中包含我们自己对STL std::string的扩展,这个类在字符串之上提供了所有种类的功能;拆分、格式化、到/从base64等。最近,我们被要求使这个字符串unicode“友好”,基本上它需要支持中文、日文、阿拉伯文等字符。经过初步研究,这在Linux端似乎很好,因为每件事本身都是UTF-8,但我在Windows端遇到了麻烦;让STL std::string在windows上作为UTF-8工作有什么诀窍吗?有可能吗?有更好的办法吗?理想情况下,我们将基于std::string,因为这是Linux中string类的基础C++ 如何使STL std::string在windows上与unicode一起工作?,c++,windows,string,unicode,stl,C++,Windows,String,Unicode,Stl,在我的公司,我们有一个跨平台(Linux和Windows)库,其中包含我们自己对STL std::string的扩展,这个类在字符串之上提供了所有种类的功能;拆分、格式化、到/从base64等。最近,我们被要求使这个字符串unicode“友好”,基本上它需要支持中文、日文、阿拉伯文等字符。经过初步研究,这在Linux端似乎很好,因为每件事本身都是UTF-8,但我在Windows端遇到了麻烦;让STL std::string在windows上作为UTF-8工作有什么诀窍吗?有可能吗?有更好的办法吗
谢谢,您看过
std::wstring
了吗?它是std::basic_string
的一个版本,用于wchar\u t
,而不是std::string
使用的char
。将UTF-8代码点放入std::string
应该可以,无论平台如何。Windows上的问题是,几乎没有其他任何东西需要UTF-8,也没有任何东西需要UTF-8,而是需要UTF-16。您可以切换到存储UTF-16(至少在大多数Windows编译器上)的std::wstring
,也可以编写其他接受UTF-8的例程(可能通过转换为UTF-16,然后传递到操作系统)。在您的问题中存在一些误解
-
< C++ > STL处理不存在编码。
本质上是一个字节字符串,而不是字符字符串。因此,在其中填充UTF-8编码的Unicode应该没有问题。但是,请记住,所有std::string
函数也可以处理字节,因此string
将给出字节数,而不是字符数myString.length()
- Linux并不是天生的UTF-8。现在大多数发行版默认为UTF-8,但不应依赖它
- 在代码的跨平台部分使用std::string。假设它始终包含UTF-8字符串
- 在代码的Windows部分,显式使用Windows API的“广泛”版本,即编写例如CreateFileW而不是CreateFile。这允许避免依赖于构建系统配置
- 在platfrom抽象层中,根据需要在UTF-8和UTF-16之间进行转换(MultiByteToWideChart/WideCharToMultiByte)
然后在业务代码中使用tstring。可以使用包装器/重载来简化std::string和std::tstring之间的转换,但这仍然会增加很多麻烦typedef std::basic_string tstring
- 在任何地方使用
。由于Windows上的std::wstring
是16位的,因此没有多大帮助,因此您必须限制自己使用BMP,或者进行大量复杂操作,以使代码能够跨平台处理Unicode。在后一种情况下,UTF-8的所有好处都消失了wchar\u t
- 在特定部分的平台中使用ATL/WTL/MFC
;在跨平台部分中使用CString
。这实际上是我上面推荐的一个变体std::string
在许多方面优于CString
(在我看来)。但它引入了额外的依赖性,因此并不总是可以接受或方便std::string
Boost::wpath
)。避免std::string
和std::fstream
在Windows API和C运行时库中,char*
参数被解释为在“ANSI”代码页中编码。问题在于,这一点
我处于类似的情况,正处于从Windows到Linux移植软件的过程中,同时也使其成为Unicode意识。我们为此采取的方法是:
- 使用UTF-8作为字符串的默认编码
- 在特定于Windows的代码中,始终调用函数的“W”版本,根据需要在UTF-8和UTF-16之间转换字符串参数
这也是。是-通过更加了解地区和编码 Windows对所有需要文本的内容都有两个函数调用,一个FoobarA()和一个FoobarW()。*W()函数接受UTF-16编码的字符串,*A()接受当前代码页中的字符串。但是,Windows不支持UTF-8代码页,因此您不能直接将其用于*a()函数,也不希望依赖用户设置。如果希望在Windows中使用“Unicode”,请使用支持Unicode(*W)的函数。有很多教程,通过谷歌搜索“Unicode Windows教程”应该可以得到一些 如果将UTF-8数据存储在std::字符串中,那么在将其传递给Windows之前,请将其转换为UTF-16(Windows提供了执行此操作的函数),然后将其传递给Windows 其中许多问题都是由于C/C++通常是编码不可知的
char
不是真正的字符,它只是一种整数类型。即使使用char
数组来存储UTF-8数据,如果需要访问单个代码单元,也会给您带来麻烦,因为标准没有定义char
的有符号性。州议会
std::string _old = u8"D:\\Folder\\This \xe2\x80\x93 by ABC.txt"s;
std::string _old = u8"D:\\Folder\\This \xe2\x80\x93 by ABC.txt";
std::cout << _old.data();