首页 > 解决方案 > 如何将 utf-8 中的字符串发送到 irc 服务器?

问题描述

我有一个使用 Qt 库用 C++ 编写的 irc 机器人。我将控制台文本输入存储在 std::string 中,然后我使用 QSocket 将其发布到 irc 聊天中。但问题是我想使用特殊符号(抛光字母),这些符号在聊天中显示不正确。问题是什么?我使用 QSocketis 的方式:

void Socket::poster(const QByteArray send)    
{
    mSocket->write(send);
    mSocket->flush();
    mSocket->reset();
}

我从 std::string 和 std::cin 创建的 QByteArray

他的代码很长,所以我只发布对失败的特定功能至关重要的部分

Socket类(程序中的主类,为其他类提供数据):

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
protected:
    QSslSocket *mSocket;
--------------------

    connect(mSocket, SIGNAL(readyRead()),
            this, SLOT(readyReady())
--------------------
//console input:
    QThread *thread = new QThread;
    consoleInput = new ConsoleInput();
    consoleInput->startConsole(thread, mSocket);
    consoleInput->moveToThread(thread);
    thread->start();

-------------------
void Socket::readyReady()
{
    QString data;
    data2 = data;
    mSocket->ReadOnly;
    while(mSocket->canReadLine())
    {
    data = mSocket->readLine();
    }
    mSocket->reset();
}


---------------------
void Socket::poster(const QByteArray send)   //sending to irc from many classes news, console itd
{
    mSocket->write(send);
    mSocket->flush();
    mSocket->reset();
}
-------------------
ConsoleInput class (which takes console input, which is later sent to irc chat):
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


void ConsoleInput::run()
{
    std::cout << "!ConsoleInput::run()" << "\n";

    while(1){
    std::string input;
    std::getline(std::cin, input);
    determineOption(input);

    if(input[0] != '/' || input[0] != '\\')
        postInput(input);

    input.clear();
    }
}


----------------------------------

void ConsoleInput::postInput(std::string &input)
{
    if(input[0]=='/')
        return; //this prevents bot poting "/command" to channel
    std::string lineToPost;

    std::cout << "!lineToPost - input " << input << "\n";
    ColourManipulation c;
    lineToPost = "PRIVMSG #grunge " + c.addColours(input) + "\r\n";
    emit mySignal(QByteArray::fromStdString(lineToPost)); // problem
}

标签: c++qtutf-8

解决方案


确保 std::cin/cout 可以接受并显示非 ascii 字符

检查代码是否可以接受并显示非 ascii 字符:

std::string input;
std::getline(std::cin, input);
std::cout << input;

如果您在控制台本身中没有非 ascii 字符的问题

你需要:

  1. 知道数据最初以哪种编码方式从控制台传输到std::string &input.

std::string 类型本身不使用编码 - 它会返回您放入其中的字节 - std::string.c_str() 使用什么编码?.

  1. QString使用必要的编码转换将字节导入

  2. 将结果导出QString为 UTF-8 编码QByteArray QByteArray本身也只是一个字节数组)。

  3. 将 写入QByteArray套接字。


您可以编写如下内容:

/*
From doc: QTextCodec::codecForLocale() 
Returns a pointer to the codec most suitable for this locale.
The codec will be retrieved from ICU where that backend is in use, 
otherwise it may be obtained from an OS-specific API. 
In the latter case, the codec's name may be "System".    
*/
QTextCodec *codec = QTextCodec::codecForLocale(); // In most cases, it is not UTF-8

// Or set the encoding explicitly:
//QTextCodec *codec = QTextCodec::codecForName("Shift-JIS"); // put your input encoding here

QTextDecoder *decoder = codec->makeDecoder();

QByteArray chunk = QByteArray::fromStdString(input);

QString string = decoder->toUnicode(chunk);
delete decoder;

emit mySignal(string.toUtf8());

请注意,您只能避免std::string和使用QString

QString使用起来更舒服,并且一旦正确接收到数据,它总是在内部以相同的已知格式存储数据,尽管std::string不知道它存储什么数据。

如何从控制台QString直接读取:

QTextStream in(stdin);
in.setCodec(<your console codec>);

QString input = in.readLine();    

请参阅QTextCodecQTextStream

另请阅读每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求(没有借口!)


推荐阅读