C++ 将 QString 转换为 char * 的干净方法(不是 const char* !!!!)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17936160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:35:30  来源:igfitidea点击:

Clean way to convert QString to char * (not const char* !!!!)

c++qt

提问by Gilles Grandguillaume

I have an ugly code for this stuff (create a c char pointer and copy the QString in it) but maybe ... exist in QT an elegant way ...

我有一个丑陋的代码来处理这些东西(创建 ac char 指针并在其中复制 QString)但也许......以优雅的方式存在于 QT 中......

actual code :

实际代码:

QString maquina is a method parameter.

char *c_maquina = new char[maquina.length() + 1];
strcpy(c_maquina, maquina.toStdString().c_str());

just for information I need a REAL char* not a simple const char* so this code not work :

仅供参考,我需要一个真正的 char* 而不是一个简单的 const char* 所以这段代码不起作用:

idMaquina.toLatin1().data();

I can't use http://developer.qt.nokia.com/faq/answer/how_can_i_convert_a_qstring_to_char_and_vice_versa

我不能使用http://developer.qt.nokia.com/faq/answer/how_can_i_convert_a_qstring_to_char_and_vice_versa

回答by Pavel Strakhov

This is simple:

这很简单:

QByteArray array = string.toLocal8Bit();
char* buffer = array.data();

You can also use toLatin1or toUtf8instead of toLocal8Bit. Note that neither of them can be queued with datacall. And toStdString().c_str()is also invalid. This is because any QByteArrayor std::stringproduced in such a way is temporary and will be destroyed immediately destroying char buffer with it. You need to store QByteArrayin a local variable while you're using the buffer.

您也可以使用toLatin1toUtf8代替toLocal8Bit。请注意,它们都不能与data呼叫排队。而且toStdString().c_str()也是无效的。这是因为以这种方式产生的任何QByteArraystd::string产生的都是临时的,并且会立即被销毁并用它销毁 char 缓冲区。QByteArray在使用缓冲区时,您需要存储在局部变量中。

Also note that Qt provides QByteArrayclass to deal with char arrays. Generally there is no need to use char*, you can do almost anything with QByteArray.

还要注意,Qt 提供QByteArray了处理字符数组的类。一般没必要用char*,用它几乎可以做任何事 QByteArray

回答by jonathanzh

I think the solution depends on the type of the characters to be converted, and whether a C-style function with "char *" type arguments needs to be integrated/called.

我认为解决方案取决于要转换的字符的类型,以及是否需要集成/调用带有“char *”类型参数的 C 样式函数。

  1. If a C-style function needs to be integrated/called, do not use toStdString() followed by c_str(), as the return value type is "const char *" which is not suitable for a C-style function.
  2. Use toLatin1() followed by data() for ASCII characters.
  3. Use toLocal8Bit() or toUtf8() followed by data() for other UTF8 characters than ASCII ones.
  1. 如果需要集成/调用 C 风格的函数,不要使用 toStdString() 后跟 c_str(),因为返回值类型是“const char *”,不适合 C 风格的函数。
  2. 对 ASCII 字符使用 toLatin1() 后跟 data()。
  3. 对于除 ASCII 字符以外的其他 UTF8 字符,使用 toLocal8Bit() 或 toUtf8() 后跟 data()。

If several solutions can be used for your specific case, their efficiency levels may be slightly different, which I have not tested.

如果几种解决方案可以用于您的特定情况,它们的效率水平可能略有不同,我没有测试过。

The following test program shows how to use these solutions:

以下测试程序展示了如何使用这些解决方案:

#include <QCoreApplication>
#include <QDebug>

// This is a C-style test function which needs an argument of type "char *":
void my_c_func(char * my_c_str)
{
    printf("    my_c_str[%s]\n", my_c_str);
}

// This is a program which tests the conversion from "QString" to "char *":
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // Case 1: ASCII characters
    // ========================

    QString qString1 = "French";
    qDebug().nospace().noquote() << "qString1[" << qString1 << "]";  // qString1[French]

    // Solution 1.1: to Latin1 QByteArray, followed by data() in 2 steps:
    QByteArray latin1BAString1 = qString1.toLatin1();
    char * latin1_c_str1 = latin1BAString1.data();
    qDebug().nospace().noquote() << "latin1_c_str1[" << latin1_c_str1 << "]"; // latin1_c_str1[French]
    my_c_func(latin1_c_str1);

    // Solution 1.2: to local 8-bit QByteArray, followed by data() in 2 steps:
    QByteArray local8bitBAString1 = qString1.toLocal8Bit();
    char * local8bit_c_str1 = local8bitBAString1.data();
    qDebug().nospace().noquote() << "local8bit_c_str1[" << local8bit_c_str1 << "]"; // local8bit_c_str1[French]
    my_c_func(local8bit_c_str1);

    // Solution 1.3: to UTF8 QByteArray, followed by data() in 2 steps:
    QByteArray utf8BAString1 = qString1.toUtf8();
    char * utf8_c_str1 = utf8BAString1.data();
    qDebug().nospace().noquote() << "utf8_c_str1[" << utf8_c_str1 << "]"; // utf8_c_str1[French]
    my_c_func(utf8_c_str1);

    // !!! Try: Solution 1.4: to std::string , followed by c_str() in 2 steps:
    std::string stdString1 = qString1.toStdString();
    const char * stdstring_c_str1 = stdString1.c_str(); // "const" must be used !
    qDebug().nospace().noquote() << "stdstring_c_str1[" << stdstring_c_str1 << "]"; // stdstring_c_str1[French]
    // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!!
    // my_c_func(stdstring_c_str1);

    qDebug() << "";

    // Case 2: Non-ASCII characters
    // ============================

    QString qString2 = "fran?ais";
    qDebug().nospace().noquote() << "qString2[" << qString2 << "]";  // qString2[fran?ais]

    // !!! Try: Solution 2.1: to Latin1 QByteArray, followed by data() in 2 steps:
    QByteArray latin1BAString2 = qString2.toLatin1();
    char * latin1_c_str2 = latin1BAString2.data();
    qDebug().nospace().noquote() << "latin1_c_str2[" << latin1_c_str2 << "]"; // latin1_c_str2[fran?ais] ---> NOT GOOD for non-ASCII characters !!!
    my_c_func(latin1_c_str2);

    // Solution 2.2: to Local 8-bit QByteArray, followed by data() in 2 steps:
    QByteArray local8bitBAString2 = qString2.toLocal8Bit();
    char * local8bit_c_str2 = local8bitBAString2.data();
    qDebug().nospace().noquote() << "local8bit_c_str2[" << local8bit_c_str2 << "]"; // local8bit_c_str2[fran?ais]
    my_c_func(local8bit_c_str2);

    // Solution 2.3: to UTF8 QByteArray, followed by data() in 2 steps:
    QByteArray utf8BAString2 = qString2.toUtf8();
    char * utf8_c_str2 = utf8BAString2.data();
    qDebug().nospace().noquote() << "utf8_c_str2[" << utf8_c_str2 << "]"; // utf8_c_str2[fran?ais]
    my_c_func(utf8_c_str2);

    // !!! Try: Solution 2.4: to std::string, followed by c_str() in 2 steps:
    std::string stdString2 = qString2.toStdString();
    const char * stdstring_c_str2 = stdString2.c_str(); // "const" must be used !
    qDebug().nospace().noquote() << "stdstring_c_str2[" << stdstring_c_str2 << "]"; // stdstring_c_str2[fran?ais]
    // invalid conversion from 'const char*' to 'char*': ---> NOT GOOD for use by a C-style function !!!
    // my_c_func(stdstring_c_str2);

    return a.exec();
}

The above code has been tested using Qt 5.4 for Linux.

上面的代码已经使用 Qt 5.4 for Linux 进行了测试。

A second subject involved in this question is whether we can chain functions together during this 2-step conversion process:

这个问题涉及的第二个主题是我们是否可以在这个两步转换过程中将函数链接在一起:

<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?

<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?

I think this depends on "AnotherClass" and on the type of characters to be converted. Based on some documentation on QString, QByteArray and std::string, it appears that it is safe to write:

我认为这取决于“AnotherClass”和要转换的字符类型。根据有关 QString、QByteArray 和 std::string 的一些文档,似乎可以安全地编写:

<myQString>.toStdString().c_str(); // OK.

<myQString>.toStdString().c_str(); // OK.

<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.

<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.

But the following lines should be avoided:

但应避免以下几行:

<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !

<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !

<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !

<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !

回答by Jacob Ramey

I use this in my code all the time

我一直在我的代码中使用它

char * toCharP(QString in)
{
    QByteArray a; a.append(in);
    return a.data();
}

回答by inetknght

QString::toLatin1().data() gives you a const char* because it gives you its internal buffer. The reason it's const is because you're not supposed to modify it.

QString::toLatin1().data() 给你一个 const char* 因为它给你它的内部缓冲区。它是 const 的原因是因为你不应该修改它。

So if you want to modify it, you have to copy that data to some other buffer... such as that one you just allocated using new().

因此,如果您想修改它,您必须将该数据复制到某个其他缓冲区……例如您刚刚使用 new() 分配的那个缓冲区。

回答by Yakk - Adam Nevraumont

std::vector<char> result;
result.reserve( qstr.length()+1 ); // +1 might not be needed, not sure how QString counts
result.insert( result.end(), qstr.begin(), qstr.end() );
char* ptr = result.data(); // while retval exists, retval.data() is a char* pointing to a buffer

回答by fjardon

QByteArray contains a non const version of data(). See: http://qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data

QByteArray 包含一个非 const 版本的data(). 请参阅:http: //qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data

回答by Xirdus

Sometimes, there's just no way to keep your code at top beauty. Deal with it. You might wrap it in a little helper function, taking QString in parameter and returning char*, if you really want.

有时,没有办法让您的代码保持最佳状态。处理它。如果您真的需要,您可以将它包装在一个小辅助函数中,将 QString 作为参数并返回 char*。