2015-10-16 203 views
2

我有一个关于字符串文字如何存储在内存中的C++的问题。我知道char是按照他们的ASCII码存储的,但我宁愿在Unicode字符集之后。原因是我试图处理一些地区。让我们假设我想要做的是将小写字符转换为大写字母。这个工程在Xcode终端,如何将字符串文字存储在内存中的c + +?

#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 termial实际挂起。它是可以修改wcin流假定为C编码wcin.imbue(std::locale());,这仍然给在Xcode相同的输出,但在OS X终端给出如下:

Output: 
Write something>> åäö 
3 
ŒŠš 

所以问题很明显地与编码。所以我想知道如何将字符串文字实际存储在C++的内存中。这可以分成两种不同的情况。

案例1:在源代码中键入的字符串文字,例如wstring str {L"åäö"};

案例2:通过标准输入流输入的字符串(在这种情况下为wcin)。

这两种情况不一定以相同的方式存储字符串。我知道unicode是一个字符集,utf-8是一种编码,所以我更想知道的是,如果字符串文字在存储在内存中时编码,那么情况如何。此外,如果有人知道如何以自动的方式识别当前终端中使用的编码,那将是非常好的。

BR 帕特里克

编辑

我得到一些注释的,尽管他们中的一些是好的,是不完全相关的问题。这意味着这个问题可能需要一些澄清。这个问题可以看作是对病态公式的概括:

“我可以假定字符串文字与他们的unicode点代码一起存储在内存中吗?”

这个问题至少有两个原因。首先它假定字符串文字是如何存储的(使用unicode代码点)。这意味着答案必须与unicode相关,尽管这种关系可能完全没有意义。此外,这个问题是一个是或者否的问题,如果答案是否定的,这个问题将不会起作用。

我也明白这可以通过测试将代码点转换为其整数等值并打印出来,但这需要我测试它对整个unicode字符集(这似乎是一种不合理的方式)。

+2

它使用'utf8',你应该使用'string','cout'等而不是'w''等价。 –

+0

@ el.pescado这就是我读过的。问题在于字母“åäö”不适合单个字符。这给了我不正确的字符串长度。你的意思是我应该将这些问题分解为两个并分别处理它们?进一步的原因是什么这是合适的? – patrik

+2

“问题在于'åäö'不适合单个字符” - 这就是utf8编码的要点 - 将这些字母合并到多个字符中。最好将'length()'作为“字节数”来处理,因为它无论如何都是中断的。请参阅http://utf8everywhere.org/和http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful –

回答

1

首先将文件解释为一系列字符的方式是实现定义的。您必须查阅您的编译器文档以确定这一点。

其次使用的字符集也是实现定义的。所以你必须再次咨询你的编译器。

当您插入非ASCII字符(可能也使用ascii)时,可能发生的情况是编译器会以不同的方式解释它们。您必须检查不同的编译器实际上是否可以处理相同的编码,最可能使用的源编码是UTF-8。

此外,也许你会更好地使用UTF-8编码文本的大部分程序(只有靠近API,需要wchar_t需要这样处理字符串)。

底线。确保您的编译器逐字地存储字符串字面值并使用普通(窄)字符串,并使用以UTF-8编码保存的编辑器。

相关问题