C++ std::string、std::wstring和UTF8

C++ std::string、std::wstring和UTF8,c++,string,utf-8,C++,String,Utf 8,我想使用UTF-8编码的字符串(很抱歉,如果这是一个错误的措辞,请纠正我,以便我理解什么是正确的)。另外,我希望我的程序是跨平台的 IIUC,正确的方法是使用std::wstring,然后将其转换为UTF8。问题是,我认为Linux上的std::string已经用UTF8编码(我可能错了) 那么,用尽可能少的条件代码创建std::{w}字符串的UTF8表示的最佳方法是什么呢 字符串是常量,它们是硬编码的,将在SQLite查询中使用 注意:我将尝试使用XCode 5,希望它符合C++11。在发布此

我想使用UTF-8编码的字符串(很抱歉,如果这是一个错误的措辞,请纠正我,以便我理解什么是正确的)。另外,我希望我的程序是跨平台的

IIUC,正确的方法是使用std::wstring,然后将其转换为UTF8。问题是,我认为Linux上的std::string已经用UTF8编码(我可能错了)

那么,用尽可能少的条件代码创建std::{w}字符串的UTF8表示的最佳方法是什么呢

字符串是常量,它们是硬编码的,将在SQLite查询中使用

注意:我将尝试使用XCode 5,希望它符合C++11。

在发布此答案后,问题发生了变化,并补充说字符串是用于SQL查询的硬编码文本。对于这个简单的
u8
字符串是一个简单的解决方案,这里回答的部分变得无关紧要。我不打算通过这个或进一步的改变来追问这个问题

我想使用UTF-8编码的字符串(很抱歉,如果这是一个错误的措辞,请纠正我,以便我理解什么是正确的措辞)。另外,我希望我的程序是跨平台的

那你真倒霉

Microsoft的文档明确指出,他们的
setlocale
不支持UTF-8:

可用的语言环境名称、语言、国家/地区代码和代码页集包括Windows NLS API支持的所有语言环境名称、语言、国家/地区代码和代码页,但每个字符需要两个以上字节的代码页除外,如UTF-7和UTF-8。如果提供UTF-7或UTF-8的代码页值,
setlocale
将失败,返回
NULL


注意:尽管它不起作用™, 有很多网站和博客,甚至可能是书籍,以一种鸵鸟式的方式推荐这种方法。他们通常看起来很权威。但是这些信息都是垃圾


用尽可能少的条件代码创建std::{w}字符串的UTF8表示的最佳方法是什么

这取决于你有什么可用的。标准库提供了
std::codecvt
。以前有人问过并回答过,例如:()

它们是硬编码的

如果所有有问题的字符串都是硬编码的字符串文字,那么您不需要任何特殊的东西

声明此类字符串时使用
u8
前缀将确保它们以UTF-8编码。在每个支持C++11此功能的平台上。此类字符串的类型为
const char[]
,与常规字符串文字类似:

const char my_utf8_literal[] = u8"Some String.";
当然,它们也可以存储在
std::string
(而不是
wstring
)中:


您说过您的目标是在SQLite查询和命令中使用它们。在这种情况下,让一切都正常工作应该很容易。您将使用SQLite的字符串格式化命令来构建查询,虽然它们对UTF-8是盲的,但只要您的所有输入都是UTF-8,输出也将是有效的UTF-8。所以应该不会有任何问题。

对于UTF-8处理,有一个名为。它提供了std::string或更具体地说std::u32string的插入式替换(::value_类型为char32_t,但数据表示为utf8,带有
char
)。这或多或少是在C++11中处理utf8的最简单方法

字符串是常量,它们是硬编码的,将被使用 在SQLite查询中

如果您有硬编码字符串,则只需将源文件的编码更改为UTF8,并将
U
-前缀前置到字符串文字,然后使用该前缀可以构造一个
UTF8\U string
类来处理它

那么,创建UTF8表示的最佳方法是什么 std::{w}字符串是否具有尽可能少的条件代码

iMHO,如果你能够,不要使用WHARGETT和WString,因为它们可能是C++字符串库中最模糊和特定于平台的东西。 我希望这至少有一点帮助


干杯,雅各布

@Cheers和HTHalf,std::codecvt的便携性如何?也是仅C++11吗?@Igor:
std::codevt
从C++98开始就存在,但直到C++11才添加UTF-8支持。这是非常可移植的,因为它是标准库的一部分。不支持UTF-8语言环境的Windows与在字符串中使用UTF-8有什么关系?在我看来,这只会影响将这些字符串传递到Windows API的代码,而跨平台代码根据定义是不会这样做的。好吧,但这并不能真正改变问题。使用UTF-8字符串与区域设置无关。除非你想让他们这么做。事实上,OP甚至没有提到地区。这并不能回答我的问题。我使用UTF-8在那些甚至从来没有考虑过C++的蹩脚的区域支持的项目中是很好的。你指的是“使用”?字符串的编码是由创建该字符串的代码决定的。你从哪里得到这些你想以某种未指明的方式“使用”的字符串?你到底打算如何“使用”它们@一二三, SQLite API将接受编码为UTF8字符串的查询字符串,以支持非英语的表名和数据库名。@igor:您没有回答nicol的问题:这些字符串来自哪里?用户输入?命令行参数?硬编码为字符串文字?还有什么?不幸的是,在标准C++中没有有用的Unicode支持。我相信C++中最常用的处理Unicode的方法是ICU.if,我使用“STD::string MyUutf8Stry= U8”一些字符串“;”,我仍然可以使用“MyUutF8Stry.cString()”,对吗?SQLite有C接口,所以…@Igor:是的。只有以某种方式解释字符串的机制(例如字符分类、文件名、i/o)才会受到影响。
std::string my_utf8_string = u8"Some String.";