加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Windows控制台和Qt Unicode文本

发布时间:2020-12-13 19:28:33 所属栏目:Windows 来源:网络整理
导读:我花了一整天的时间,试图找出这个没有运气.我看到无处不在,但没有运气与工作代码. 操作系统:Win XP Sp2 IDE框架:C,Qt Creator 2.0. 我试图将一些unicode(UTF-8)文本输出到Windows控制台,但是我看到的都是乱码代替unicode字符.我知道win控制台支持unicode(
我花了一整天的时间,试图找出这个没有运气.我看到无处不在,但没有运气与工作代码.

操作系统:Win XP Sp2
IDE&框架:C,Qt Creator 2.0.

我试图将一些unicode(UTF-8)文本输出到Windows控制台,但是我看到的都是乱码代替unicode字符.我知道win控制台支持unicode(自从2000年以来)…至少根据维基百科和许多网络,但我不知道如何使它与Qt工作.我看过的大多数“解决方案”(没有看到很多)使用C和WInAPI技术,我不能使用,因为这不是Qt的方式.我使用QStrings和Qt!

代码下面我拿出所有不同的东西,我试图保持代码简单的帖子.希望有人可以得到代码的工作.

#include <QtCore/QCoreApplication>
#include <QString>
#include <QTextStream>          
#include <QDate>
#include <QFile>
using namespace std;

int main(int argc,char *argv[])
{
    QCoreApplication app(argc,argv);

    QTextStream qin(stdin);         
    QTextStream qout(stdout);       

    //The last 2 chars in QString each need a double slash for an accent.
    QString szqLine = QString::fromUtf8("abc áéüó?ú ??");

    //I want this text console output to be in red text color.
    qout << "Bellow are some unicode characters: " << endl; 

    //The Win XP console does not display the unicode chars correctly!!
    //The cosole does not display unicode chars even though it is capable
    //according to wikipedia.  I just don't know how with Qt.
    //I want this text output in white(or default font color,not red.)
    qout << szqLine << endl;

    //Would be nice to get some unicode input from console too.
    qout << "Write some unicode chars like above: " << endl;
    QString szqInput;
    szqInput = QString::fromUtf8(qin.readLine());
    qout << "You wrote: " << endl;
    qout << szqInput << endl;



    return app.exec();
}
好的,我用这段代码做了一些测试.不需要专门的控制台设置.
#include <QTextStream>

#ifdef Q_OS_WIN32
#include <windows.h>
#include <iostream>
#else
#include <locale.h>
#endif

class ConsoleTextStream: public QTextStream {
  public:
    ConsoleTextStream();
    ConsoleTextStream& operator<<(const QString &string);
};

ConsoleTextStream::ConsoleTextStream():
  QTextStream(stdout,QIODevice::WriteOnly)
{
}

ConsoleTextStream& ConsoleTextStream::operator<<(const QString &string)
{
#ifdef Q_OS_WIN32
  WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),string.utf16(),string.size(),NULL,NULL);
#else
  QTextStream::operator<<(string);
#endif
  return *this;
}

class ConsoleInput: public QTextStream {
public:
  ConsoleInput();
  QString readLine();
};

ConsoleInput::ConsoleInput():
  QTextStream(stdin,QIODevice::ReadOnly)
{
}

QString ConsoleInput::readLine()
{
#ifdef Q_OS_WIN32
  const int bufsize = 512;
  wchar_t buf[bufsize];
  DWORD read;
  QString res;
  do {
    ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE),buf,bufsize,&read,NULL);
    res += QString::fromWCharArray(buf,read);
  } while (read > 0 && res[res.length() - 1] != 'n');
  // could just do res.truncate(res.length() - 2),but better be safe
  while (res.length() > 0 
         && (res[res.length() - 1] == 'r' || res[res.length() - 1] == 'n'))
    res.truncate(res.length() - 1);
  return res;
#else
  return QTextStream::readLine();
#endif
}

int main()
{
#ifndef Q_OS_WIN32
  setlocale(LC_ALL,"");
#endif
  ConsoleTextStream qout;
  qout << QString::fromUtf8("Текст на иврите: ??? ??????? ?????? ????? ????? ?????n");
  qout << QString::fromUtf8("Текст на японском: ※当サイト内コンテンツ?画像?写真データの、転載?転用?加工?無断複製は禁止いたします.n");
  qout << QString::fromUtf8("Текст на европейском: áéüó?ú ??n");
  qout << flush; // needed on Linux
  ConsoleInput qin;
  QString s = qin.readLine();
  qout << s << endl;
  s = qin.readLine(); // one more time,to ensure we read everything ok
  qout << s << endl;
  return 0;
}

在Windows上,除了俄罗斯和欧洲之外,它会打印所有文字的方框.看起来,Lucida控制台不支持希伯来语和日语.有趣的是,当我将文本从控制台复制到剪贴板,然后粘贴到支持Unicode的地方(例如在浏览器中)时,它会正确显示.这证明Windows实际上是输出Unicode,只是不显示它.需要一些支持Unicode的控制台字体.

请注意,在上面的示例中,我仅覆盖了一个运算符<()(),但是如果我想使用它们,我将需要覆盖它们,因为它们返回QTextStream&但不是虚拟的,所以有必要使它们都返回ConsoleTextStream& amp;其他的东西,如qout<< 1 < someUnicodeString将无法正常工作. 我也在Linux上用UTF-8语言环境测试了这个例子,效果很好. 使用ReadConsoleW()的控制台输入工作是因为默认情况下,控制台配置为所谓的线路输入模式,所以它等待直到用户点击Enter,但不等到足够的字符可用来填充缓冲区,所以它完全正好是我们想要:读取一行,只要缓冲区大小就够了.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读