如何在控制台/屏幕上打印如下字符串:€áa¢cée£
?我试过这个:
#include <iostream>
#include <string>
using namespace std;
wstring wStr = L"€áa¢cée£";
int main (void)
{
wcout << wStr << " : " << wStr.length() << endl;
return 0;
}
哪个不行。即使令人困惑,如果我从字符串中删除€
,则打印输出如下:?a?c?e? : 7
但字符串中的€
,€
字符后不会打印任何内容。
如果我在python中编写相同的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
wStr = u"€áa¢cée£"
print u"%s" % wStr
它在同一个控制台上正确打印出字符串。我在c ++中缺少什么(好吧,我只是一个菜鸟)?干杯!!
<小时/> 更新1:基于n.m.的建议
#include <iostream>
#include <string>
using namespace std;
string wStr = "€áa¢cée£";
char *pStr = 0;
int main (void)
{
cout << wStr << " : " << wStr.length() << endl;
pStr = &wStr[0];
for (unsigned int i = 0; i < wStr.length(); i++) {
cout << "char "<< i+1 << " # " << *pStr << " => " << pStr << endl;
pStr++;
}
return 0;
}
首先,它报告14
作为字符串的长度:€áa¢cée£ : 14
是因为它每个字符计算2个字节?
我得到的全部是:
char 1 # ? => €áa¢cée£
char 2 # ? => ??áa¢cée£
char 3 # ? => ?áa¢cée£
char 4 # ? => áa¢cée£
char 5 # ? => ?a¢cée£
char 6 # a => a¢cée£
char 7 # ? => ¢cée£
char 8 # ? => ?cée£
char 9 # c => cée£
char 10 # ? => ée£
char 11 # ? => ?e£
char 12 # e => e£
char 13 # ? => £
char 14 # ? => ?
作为最后的cout输出。所以,实际问题仍然存在,我相信。干杯!!
更新2:基于n.m.的第二个建议
#include <iostream>
#include <string>
using namespace std;
wchar_t wStr[] = L"€áa¢cée£";
int iStr = sizeof(wStr) / sizeof(wStr[0]); // length of the string
wchar_t *pStr = 0;
int main (void)
{
setlocale (LC_ALL,"");
wcout << wStr << " : " << iStr << endl;
pStr = &wStr[0];
for (int i = 0; i < iStr; i++) {
wcout << *pStr << " => " << static_cast<void*>(pStr) << " => " << pStr << endl;
pStr++;
}
return 0;
}
这就是我得到的结果:
€áa¢cée£ : 9
€ => 0x1000010e8 => €áa¢cée£
á => 0x1000010ec => áa¢cée£
a => 0x1000010f0 => a¢cée£
¢ => 0x1000010f4 => ¢cée£
c => 0x1000010f8 => cée£
é => 0x1000010fc => ée£
e => 0x100001100 => e£
£ => 0x100001104 => £
=> 0x100001108 =>
为什么报告为9
而不是8
?或者这是我应该期待的?干杯!!
答案 0 :(得分:7)
将L
放在字符串文字之前。使用std::string
,而不是std::wstring
。
UPD:有一个更好(正确)的解决方案。保持wchar_t,wstring和L,并在程序开头调用setlocale(LC_ALL,"")
。
无论如何,您应该在程序开头调用setlocale(LC_ALL,"")
。这会指示您的程序使用您环境的语言环境,而不是默认的“C”语言环境。您的环境有一个UTF-8,所以一切都应该有效。
不调用setlocale(LC_ALL,"")
,该程序使用UTF-8序列而不“意识到”它们是UTF-8。如果终端上印有正确的UTF-8序列,它将被解释为UTF-8,一切都会好看。如果您使用string
和char
会发生这种情况:gcc使用UTF-8作为字符串的默认编码,并且ostream愉快地打印它们而不应用任何转换。它认为它有一系列ASCII字符。
但是当你使用wchar_t
时,一切都会中断:gcc使用UTF-32,不应用正确的重新编码(因为语言环境是“C”),输出是垃圾。
当你打电话给setlocale(LC_ALL,"")
时,程序知道它应该将UTF-32重新编码为UTF-8,而且一切都很好并再次花哨。
这一切都假设我们只想使用UTF-8。使用任意语言环境和编码超出了本答案的范围。