如何在Linux/OS X上打印字符串

How to print wstring on Linux/OS X?

本文关键字:打印 字符串 OS Linux      更新时间:2023-10-16

如何在控制台/屏幕上打印这样的字符串:€á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 # ? => ?

作为最后一个计数输出。所以,我认为真正的问题仍然存在。干杯! !


更新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 ?或者这是我应该期待的?干杯! !

在字符串字面值前删除L。使用std::string,而不是std::wstring

有一个更好的(正确的)解决方案。保留wchar_t, wstring和L,并在程序开头调用setlocale(LC_ALL,"")。 无论如何,您应该在程序的开头调用setlocale(LC_ALL,"")。这将指示程序使用环境的语言环境,而不是默认的"C"语言环境。您的环境有一个UTF-8,所以一切都应该工作。

在不调用setlocale(LC_ALL,"")的情况下,程序使用UTF-8序列而不"意识到"它们是UTF-8。如果在终端上打印了正确的UTF-8序列,它将被解释为UTF-8,一切看起来都很好。如果您使用stringchar,就会发生这种情况:gcc使用UTF-8作为字符串的默认编码,ostream很高兴地打印它们,而不应用任何转换。它认为它有一个ASCII字符序列。

但是当您使用wchar_t时,一切都中断了:gcc使用UTF-32,没有应用正确的重新编码(因为区域设置是"C"),输出是垃圾。

当你调用setlocale(LC_ALL,"")时,程序知道它应该将UTF-32重新编码为UTF-8,然后一切又好了。

这一切都假设我们只想使用UTF-8。使用任意区域设置和编码超出了这个答案的范围。