Myślę, że rozwiązanie zależy od typu konwertowanych znaków i od tego, czy funkcja typu C z argumentami typu "char *" musi zostać zintegrowana/wywołana.
- Jeżeli funkcja stylu C musi być włączone/wywoływanego, nie stosować toStdString(), a następnie (c_str), a typ wartość jest równa „char *”, co nie jest korzystne dla C- funkcja stylu.
- Użyj doLatin1(), a następnie danych() dla znaków ASCII.
- Używaj dlaLocal8Bit() lub toUtf8(), a następnie danych() dla innych znaków UTF8 niż ASCII.
Jeśli w konkretnym przypadku można zastosować kilka rozwiązań, ich poziomy wydajności mogą się nieznacznie różnić, czego nie przetestowałem.
następujący program testowy pokazuje, jak korzystać z tych rozwiązań:
#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();
}
Powyższy kod został przetestowany przy użyciu Qt 5.4 for Linux.
Drugim przedmiotem zaangażowany w tej kwestii jest to, czy możemy funkcje łańcuchowe razem podczas tego 2-etapowego procesu konwersji:
<myQString>.to<AnotherClass>().<getCPointer>(); // OK or not?
myślę, że to zależy od „AnotherClass” oraz od rodzaju znaków do być przekonwertowanym. Na podstawie jakiejś dokumentacji QString, QByteArray i std :: string, wydaje się, że jest to bezpieczne, aby napisać:
<myQString>.toStdString().c_str(); // OK.
<myQString>.toUtf8().data(); // Should be OK as QString is Unicode string.
Ale należy unikać następujące linie:
<myQString>.toLocal8Bit().data(); // May crash if the converted QByteArray object is undefined !
<myQString>.toLatin1().data(); // May crash if the converted QByteArray object is undefined !
"Nie mogę użyć łącza" - dlaczego ten link nie nadaje się do użytku? Musisz być jaśniejszy. Wyjaśnij nie tylko problem z twoim bezpośrednim planem (uzyskaj 'char *' od 'QString'), ale co skłoniło cię do myślenia, że tego potrzebujesz. – Yakk
Yakk, nie mogę użyć przekonwertować jak wyjaśnić w linku, ponieważ jest konwersją między QString i char * (bez możliwości nadpisania znaku *). Potrzebuję char * z możliwym nadpisaniem, mam nadzieję, funkcja QString dla to ... proszę o komentarz. –
Nadal nie wiem, dlaczego nie można użyć połączonego rozwiązania. Czy problem polega na tym, że kod przykładowy używa "const char *", a nie "char *"? '.data()' zwraca 'char *'. Ponadto, co masz nadzieję zrobić z zapisywalnym 'char *'? – Yakk