9

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

实际代码:

QString maquina is a method parameter.

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

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

idMaquina.toLatin1().data();

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

4

7 回答 7

37

这很简单:

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

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

另请注意,Qt 提供QByteArray了处理 char 数组的类。一般没有必要使用char*,几乎可以做任何事情 QByteArray

于 2013-07-30T11:11:54.410 回答
1

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

  1. 如果需要集成/调用 C 风格的函数,请不要使用 toStdString() 后跟 c_str(),因为返回值类型是“const char *”,不适合 C 风格的函数。
  2. 对 ASCII 字符使用 toLatin1() 后跟 data()。
  3. 使用 toLocal8Bit() 或 toUtf8() 后跟 data() 用于其他 UTF8 字符而不是 ASCII 字符。

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

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

#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();
}

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

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

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

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

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

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

但应避免以下行:

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

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

于 2015-07-03T00:35:34.257 回答
1

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

char * toCharP(QString in)
{
    QByteArray a; a.append(in);
    return a.data();
}
于 2016-07-09T18:41:52.680 回答
0

QByteArray 包含一个非常量版本的data(). 见:http: //qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data

于 2013-07-30T10:16:58.070 回答
0
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
于 2013-07-30T00:32:37.173 回答
0

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

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

于 2013-07-30T00:10:17.333 回答
-1

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

于 2013-07-30T00:03:56.073 回答