简体   繁体   English

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

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

I have an ugly code for this stuff (create ac 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 : 只是为了获取信息我需要一个REAL 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

This is simple: 这很简单:

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

You can also use toLatin1 or toUtf8 instead of toLocal8Bit . 您也可以使用toLatin1toUtf8而不是toLocal8Bit Note that neither of them can be queued with data call. 请注意,它们都不能与data调用排队。 And toStdString().c_str() is also invalid. toStdString().c_str()也是无效的。 This is because any QByteArray or std::string produced in such a way is temporary and will be destroyed immediately destroying char buffer with it. 这是因为以这种方式生成的任何QByteArraystd::string都是临时的,并且会立即销毁使用它破坏char缓冲区。 You need to store QByteArray in a local variable while you're using the buffer. 在使用缓冲区时,需要将QByteArray存储在局部变量中。

Also note that Qt provides QByteArray class to deal with char arrays. 另请注意,Qt提供了QByteArray类来处理char数组。 Generally there is no need to use char* , you can do almost anything with QByteArray . 通常不需要使用char* ,你几乎可以用QByteArray做任何事情。

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. 如果需要集成/调用C风格的函数,请不要使用toStdString()后跟c_str(),因为返回值类型是“const char *”,它不适合C风格的函数。
  2. Use toLatin1() followed by data() for ASCII characters. 对于ASCII字符,使用toLatin1()后跟data()。
  3. Use toLocal8Bit() or toUtf8() followed by data() for other UTF8 characters than ASCII ones. 使用toLocal8Bit()或toUtf8()后跟data()以获取除ASCII之外的其他UTF8字符。

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?

I think this depends on "AnotherClass" and on the type of characters to be converted. 我认为这取决于“AnotherClass”和要转换的字符类型。 Based on some documentation on QString, QByteArray and std::string, it appears that it is safe to write: 根据有关QString,QByteArray和std :: string的一些文档,看起来可以安全地编写:

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

<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>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !

QString::toLatin1().data() gives you a const char* because it gives you its internal buffer. QString :: toLatin1()。data()为您提供了一个const char *,因为它为您提供了内部缓冲区。 The reason it's const is because you're not supposed to modify it. 它是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()分配的缓冲区。

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

QByteArray contains a non const version of data() . QByteArray包含非const版本的data() See: http://qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data 请参阅: http//qt-project.org/doc/qt-5.0/qtcore/qbytearray.html#data

I use this in my code all the time 我一直在我的代码中使用它

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

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 *,如果您真的想要的话。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM