c++ - 如何将 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
}
解决方案
确保 std::cin/cout 可以接受并显示非 ascii 字符
检查代码是否可以接受并显示非 ascii 字符:
std::string input;
std::getline(std::cin, input);
std::cout << input;
如果您在控制台本身中没有非 ascii 字符的问题
你需要:
- 知道数据最初以哪种编码方式从控制台传输到
std::string &input
.
std::string
类型本身不使用编码 - 它会返回您放入其中的字节 - std::string.c_str() 使用什么编码?.
QString
使用必要的编码转换将字节导入将结果导出
QString
为 UTF-8 编码QByteArray
(QByteArray
本身也只是一个字节数组)。将 写入
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();
推荐阅读
- sql - MySQL - #1064 - 你的语法 'LIMIT 0, 25' 有问题
- python - 替换文本文件中的数据/字符串
- java - 是否可以在 EnvironmentPostProcessor 的实现中使用 @ConstructorBinding 绑定的不可变 @ConfigurationProperties bean?
- c++ - 如何在 C++ 中创建一个空的对象向量?
- nginx - 有没有办法使用 Nginx 将 SameSite cookie 设置为无?
- node.js - Hapi.js 无法读取 null 的属性“statusCode”
- mysql - 根据给定的计数多次插入相同的记录
- validation - 根据 Google 表格中某个范围内的选定值,在下拉列表中设置值的“子范围”列表(数据验证)
- javascript - getUserMedia 检测前置摄像头
- mongodb - 重命名 mongoDB 中的集合