如何将QString转换为std::string?

293

我正在尝试做类似这样的事情:

QString string;
// do things...
std::cout << string << std::endl;

但是代码无法编译。如何将 qstring 的内容输出到控制台(例如进行调试或其他原因)?如何将 QString 转换为 std::string

12个回答

347

你可以使用:

QString qs;
// do things
std::cout << qs.toStdString() << std::endl;

它内部使用QString::toUtf8()函数创建std::string,因此它也是Unicode安全的。 这里QString的参考文档。


85
自Qt 5.0起,QString::toStdString()现在使用QString::toUtf8()来执行转换,因此字符串的Unicode属性不会丢失(http://qt-project.org/doc/qt-5.0/qtcore/qstring.html#toStdString)。 - Emile Cormier
如果您想要检查QString::toStdString的源代码,请点击此处 - thuga
1
我该如何测试以查看它是否确实失去了Unicode属性?使用Unicode字符(例如来自英语以外的语言)会有用吗? - Yousuf Azad

255

在将 QString 转换为 std::string 时,需要记住的一件事情是 QString 是 UTF-16 编码,而 std::string 可能具有任何编码。

因此最好的方法要么是:

QString qs;

// Either this if you use UTF-8 anywhere
std::string utf8_text = qs.toUtf8().constData();

// or this if you're on Windows :-)
std::string current_locale_text = qs.toLocal8Bit().constData();

如果你指定了编解码,那么建议的(已接受的)方法可能有效。

参见:http://doc.qt.io/qt-5/qstring.html#toLatin1


1
这样做不安全,而且比正确方法稍微慢一点。您正在访问在堆栈上创建的 QByteArray 的数据。STL 字符串的构造函数之前可能会调用 QByteArray 的析构函数。创建辅助函数是最安全的方式。static inline std::string toUtf8(const QString& s) { QByteArray sUtf8 = s.toUtf8(); return std::string(sUtf8.constData(), sUtf8.size()); } - Vitali
18
@Vitali的说法不正确。"QByteArray的析构函数可能会在STL字符串的构造函数之前被调用"这句话是错误的陈述:引用标准:12.2.3临时对象在评估包含它们创建点(在语法上)的完整表达式(1.9)的最后一步中被销毁。而那里的完整表达式是std::string utf8_text = qs.toUtf8().constData();因此你的说法是不正确的。 - Artyom
8
不,那会导致非Latin1字符丢失。请尝试这个:QString s = QString::fromUtf8("árvíztűrő tükörfúrógép ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP"); std::cout << s.toStdString() << std::endl; std::cout << s.toUtf8().constData() << std::endl;。第一个是不正确的,第二个完美。您需要使用UTF8终端来测试此代码。 - Notinlist
3
就我所知,无论QString的内容是什么(非Latin1或其他),在管道运算符中使用.toStdString()总是会导致访问冲突。这是在Qt 4.8.3/MSVC++ 10/Win 7上的情况。 - Daniel Saner
@Artyom 答案应该被编辑,因为 QByteArray QString::toAscii() const 已经过时 - Tarod
显示剩余4条评论

37
如果您的最终目的是将调试信息输出到控制台,您可以使用 qDebug()
您可以像这样使用: qDebug()<<string; 它会将内容打印到控制台。与仅为调试消息转换为 std::string 相比,这种方法更好。

1
qDebug()会更好,因为它支持更多的Qt类型。 - Kamil Klimek

26
QString qstr;
std::string str = qstr.toStdString();

然而,如果您正在使用Qt:

QTextStream out(stdout);
out << qstr;

我在询问之前尝试了<< qstr,但它无法编译。不过使用qstr.toStdString()就可以了。 - augustin
4
我不这么认为。你尝试使用了std::cout << qstr,而不是QTextString(stdout) << qstr。 - chris

19

最好的做法是自己重载运算符<<,这样Qstring就可以作为可输出类型传递给任何期望此类类型的库。

std::ostream& operator<<(std::ostream& str, const QString& string) {
    return str << string.toStdString();
}

4
为什么会有人踩呢?对于我来说可能有点过度,但谁知道呢,这个可能会对我或者其他人有用。 - augustin
我喜欢这个的原因是Qt有改变它们字符串工作方式的习惯 - 而这将转换放在一个地方。 - Den-Jason

13

提供另一种方案:

QString qs;
std::string current_locale_text = qs.toLocal8Bit().constData();

可能是以下原因:

QString qs;
std::string current_locale_text = qPrintable(qs);

参见qPrintable文档,这是一个从QtGlobal返回const char *的宏。


2
即使使用了设置了-no-stl选项的Qt构建,这也可以正常工作。更多信息 - Senči

8
最简单的方法是使用QString::toStdString()

2
您可以使用这个;
QString data;
data.toStdString().c_str();

请添加一些细节,说明错误是什么以及为什么您的答案有效。 - Anantha Raju C

1

还有一种选择是使用qPrintableqUtf8Printable

E.g.:

#include <QString>
#include <iostream>

int main()
{
    QString myString = "Hello World";

    // Using qPrintable
    std::cout << "qPrintable: " << qPrintable(myString) << std::endl;

    // Using qUtf8Printable
    std::cout << "qUtf8Printable: " << qUtf8Printable(myString) << std::endl;

    return 0;
}

0
 QString data;
   data.toStdString().c_str();

在VS2017编译器中,甚至可能在xstring上抛出异常

 ~basic_string() _NOEXCEPT
        {   // destroy the string
        _Tidy_deallocate();
        }

安全(无异常)的正确方法如Artyom所述

 QString qs;

    // Either this if you use UTF-8 anywhere
    std::string utf8_text = qs.toUtf8().constData();

    // or this if you're on Windows :-)
    std::string current_locale_text = qs.toLocal8Bit().constData();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接