如何使用 C + + 打印 Unicode字符?

我试图打印一个俄罗斯“”(U + 0444西里尔小字母 EF)字符,这是一个十进制代码 1092。使用 C + + ,如何打印出这个字符?我本以为下面这些方法会奏效,但是..。

int main (){
wchar_t f = '1060';
cout << f << endl;
}
216150 次浏览

最终,这完全依赖于平台。不幸的是,在标准 C + + 中对 Unicode 的支持非常差。对于 GCC,必须将其设置为窄字符串,因为它们使用 UTF-8,而 Windows 需要宽字符串,必须将其输出为 wcout

// GCC
std::cout << "ф";
// Windoze
wcout << L"ф";

'1060'是四个字符,不会在标准下编译。如果宽字符与 Unicode 的比例为1:1(请检查区域设置) ,那么应该只将字符视为一个数字。

int main (){
wchar_t f = 1060;
wcout << f << endl;
}

若要表示字符,可以使用通用字符名称(UCN)。字符‘’的 Unicode 值为 U + 0444,因此在 C + + 中可以写成‘ u0444’或‘ U0000444’。另外,如果源代码编码支持这个字符,那么您可以直接在源代码中写入它。

// both of these assume that the character can be represented with
// a single char in the execution encoding
char b = '\u0444';
char a = 'ф'; // this line additionally assumes that the source character encoding supports this character

将这些字符打印出来取决于要打印的内容。如果你打印到一个 Unix 虚拟终端,虚拟终端使用一个支持这个字符的编码,并且这个编码与编译器的执行编码相匹配,那么你可以做以下事情:

#include <iostream>


int main() {
std::cout << "Hello, ф or \u0444!\n";
}

这个程序 没有要求“”可以用一个字符表示。在 OS X 和大多数现代 Linux 安装中,这种方法都可以很好地工作,因为源代码、执行和控制台编码都将是 UTF-8(它支持所有 Unicode 字符)。

Windows 的情况比较困难,而且有不同的权衡可能性。

如果您不需要可移植代码(您将使用 wchar _ t,在其他平台上应该避免使用这种代码) ,那么最好的方法可能是将输出文件句柄的模式设置为只接受 UTF-16数据。

#include <iostream>
#include <io.h>
#include <fcntl.h>


int main() {
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << L"Hello, \u0444!\n";
}

便携式代码更加困难。

在使用 -std=c++11编译时,可以简单地

  const char *s  = u8"\u0444";
cout << s << endl;

如果使用 Windows (注意,我们使用的是 printf () ,而不是 cout) :

//Save As UTF8 without signature
#include <stdio.h>
#include<windows.h>
int main (){
SetConsoleOutputCP(65001);
printf("ф\n");
}

不是 Unicode 而是 working-1251而不是 UTF8:

//Save As Windows 1251
#include <iostream>
#include<windows.h>
using namespace std;
int main (){
SetConsoleOutputCP(1251);
cout << "ф" << endl;
}

在 Linux 中,我可以这样做:

std::cout << "ф";

我只是复制粘贴字符从 给你和它没有失败,至少随机样本,我尝试。

Linux 的另一种解决方案:

string a = "Ф";
cout << "Ф = \xd0\xa4 = " << hex
<< int(static_cast<unsigned char>(a[0]))
<< int(static_cast<unsigned char>(a[1])) << " (" << a.length() << "B)" << endl;


string b = "√";
cout << "√ = \xe2\x88\x9a = " << hex
<< int(static_cast<unsigned char>(b[0]))
<< int(static_cast<unsigned char>(b[1]))
<< int(static_cast<unsigned char>(b[2])) << " (" << b.length() << "B)" << endl;

我需要在 UI 中显示字符串,并将其保存到 xml 配置文件中。上面指定的格式对 c + + 中的字符串很有用,我要补充的是,我们可以通过将“ u”替换为“ & # x”并在末尾添加一个“ ;”来为特殊字符提供与 xml 兼容的字符串。

例如: C + + : “ u0444”—— > XML: "&#x0444;"

这段代码适用于 Linux (C + + 11,geany,g + + 7.4.0) :

#include <iostream>


using namespace std;




int utf8_to_unicode(string utf8_code);
string unicode_to_utf8(int unicode);




int main()
{
cout << unicode_to_utf8(36) << '\t';
cout << unicode_to_utf8(162) << '\t';
cout << unicode_to_utf8(8364) << '\t';
cout << unicode_to_utf8(128578) << endl;


cout << unicode_to_utf8(0x24) << '\t';
cout << unicode_to_utf8(0xa2) << '\t';
cout << unicode_to_utf8(0x20ac) << '\t';
cout << unicode_to_utf8(0x1f642) << endl;


cout << utf8_to_unicode("$") << '\t';
cout << utf8_to_unicode("¢") << '\t';
cout << utf8_to_unicode("€") << '\t';
cout << utf8_to_unicode("🙂") << endl;


cout << utf8_to_unicode("\x24") << '\t';
cout << utf8_to_unicode("\xc2\xa2") << '\t';
cout << utf8_to_unicode("\xe2\x82\xac") << '\t';
cout << utf8_to_unicode("\xf0\x9f\x99\x82") << endl;


return 0;
}




int utf8_to_unicode(string utf8_code)
{
unsigned utf8_size = utf8_code.length();
int unicode = 0;


for (unsigned p=0; p<utf8_size; ++p)
{
int bit_count = (p? 6: 8 - utf8_size - (utf8_size == 1? 0: 1)),
shift = (p < utf8_size - 1? (6*(utf8_size - p - 1)): 0);


for (int k=0; k<bit_count; ++k)
unicode += ((utf8_code[p] & (1 << k)) << shift);
}


return unicode;
}




string unicode_to_utf8(int unicode)
{
string s;


if (unicode>=0 and unicode <= 0x7f)  // 7F(16) = 127(10)
{
s = static_cast<char>(unicode);


return s;
}
else if (unicode <= 0x7ff)  // 7FF(16) = 2047(10)
{
unsigned char c1 = 192, c2 = 128;


for (int k=0; k<11; ++k)
{
if (k < 6)  c2 |= (unicode % 64) & (1 << k);
else c1 |= (unicode >> 6) & (1 << (k - 6));
}


s = c1;    s += c2;


return s;
}
else if (unicode <= 0xffff)  // FFFF(16) = 65535(10)
{
unsigned char c1 = 224, c2 = 128, c3 = 128;


for (int k=0; k<16; ++k)
{
if (k < 6)  c3 |= (unicode % 64) & (1 << k);
else if (k < 12) c2 |= (unicode >> 6) & (1 << (k - 6));
else c1 |= (unicode >> 12) & (1 << (k - 12));
}


s = c1;    s += c2;    s += c3;


return s;
}
else if (unicode <= 0x1fffff)  // 1FFFFF(16) = 2097151(10)
{
unsigned char c1 = 240, c2 = 128, c3 = 128, c4 = 128;


for (int k=0; k<21; ++k)
{
if (k < 6)  c4 |= (unicode % 64) & (1 << k);
else if (k < 12) c3 |= (unicode >> 6) & (1 << (k - 6));
else if (k < 18) c2 |= (unicode >> 12) & (1 << (k - 12));
else c1 |= (unicode >> 18) & (1 << (k - 18));
}


s = c1;    s += c2;    s += c3;    s += c4;


return s;
}
else if (unicode <= 0x3ffffff)  // 3FFFFFF(16) = 67108863(10)
{
;  // actually, there are no 5-bytes unicodes
}
else if (unicode <= 0x7fffffff)  // 7FFFFFFF(16) = 2147483647(10)
{
;  // actually, there are no 6-bytes unicodes
}
else  ;  // incorrect unicode (< 0 or > 2147483647)


return "";
}

更多:

特别感谢回答 给你或多或少相同的问题。

对我来说,我所需要的就是 setlocale(LC_ALL, "en_US.UTF-8");

然后,我甚至可以使用原始的 wchar_t字符。

在 Linux 上,Unicode字符(UTF-16/UTF-32)可以转换成 UTF-8并打印成 std: : cout。