我有一个关于C++中字符串字面值在内存中如何存储的问题。我知道char
按照它们的ASCII码存储,但我更关心Unicode字符集。原因是我试图处理一些本地化问题。假设我想要将小写字符转换为大写字符。这在Xcode终端中可以实现。
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
wstring str {L"åäö"}; // Swedish letters
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
Output:
3
ÅÄÖ
然而,当我试图在OS X终端中运行它时,我得到的是一堆垃圾。
Output:
3
ÅÄÖ
当我向用户提示输入时,
#include <iostream>
#include <string>
#include <cctype>
#include <clocale>
using namespace std;
int main()
{
wcin.imbue(std::locale(""));
wcout.imbue(std::locale("sv_SE.Utf-8"));
const std::ctype<wchar_t>& f = std::use_facet< std::ctype<wchar_t> >(std::locale("sv_SE.Utf-8"));
//wstring str {L"åäö"};
wcout << "Write something>> ";
wstring str;
getline(wcin, str);
f.toupper(&str[0], &str[0] + str.size());
std::wcout << str.length() << std::endl;
std::wcout << str << std::endl;
}
我从Xcode终端获得垃圾信息,
Output:
Write something>> åäö
6
åäö
当我使用这些字母时,OS X终端实际上会挂起。可以修改wcin
流来假设C编码wcin.imbue(std::locale());
,在Xcode中仍然给出相同的输出,但在OS X终端中则会得到以下结果:
Output:
Write something>> åäö
3
ŒŠš
因此,问题显然与编码有关。我想知道在C++中字符串文字实际上是如何存储在内存中的。这可以分为两种不同的情况。
情况1:在源代码中键入的字符串文字,例如。
情况2:通过标准输入流输入的字符串(在这种情况下为)。
这两种情况不一定以相同的方式存储字符串。我知道Unicode是一个字符集,UTF-8是一种编码方式,所以我想知道字符串文字是否在存储在内存时被编码,如果是,那么是如何编码的。
另外,如果有人知道如何自动识别当前终端使用的编码方式,那就太好了。
问候, Patrik
编辑
我收到了一些评论,尽管其中一些很好,但并不完全与问题相关。这意味着问题可能需要一些澄清。该问题可以看作是一个相当模糊的问题的概括:
“我能假设字符串文字以它们的Unicode代码点存储在内存中吗?”
这个问题的表述很差,至少有两个原因。首先,它对字符串文字的存储方式做出了假设(以它们的Unicode代码点)。这意味着答案必须涉及Unicode,即使这种关系可能完全没有意义。此外,这个问题是一个二选一的问题,如果答案是否定的,它将毫无帮助。
我也理解这可以通过将代码点转换为其整数等效项并打印来测试,但这将需要我针对整个Unicode字符集进行测试(这似乎是一种不合理的方法)。
utf8
,则应该使用string
、cout
等而不是w-
相关的函数。 - el.pescado - нет войнеåäö
无法适应单个字符 - 这就是 utf8 编码的目的 - 将这些字母适应多个字符。最好将length()
视为“字节数”,因为它已经失效了。请参见 http://utf8everywhere.org/ 和 http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful。 - el.pescado - нет войне\xHH
或\uHHHH
符号指定明确的代码点,或将这些字符串放入某种资源文件中,在运行时加载(后者还有助于本地化)。 - Igor Tandetnik