Jak przekonwertować QString na std :: string?

229

Próbuję zrobić coś takiego:

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

ale kod się nie kompiluje. Jak wyprowadzić zawartość qstring do konsoli (np. W celu debugowania lub z innych powodów)? Jak przekonwertować QStringna std::string?

sierpień
źródło

Odpowiedzi:

222

Jedną z rzeczy, należy pamiętać przy konwersji QStringna std::stringto fakt, że QStringjest kodowana w UTF-16 podczas std::string... Może mieć żadnych kodowania.

Tak więc najlepsze byłoby:

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

Sugerowana (zaakceptowana) metoda może działać, jeśli podasz kodek.

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

Artem
źródło
Nie jest to bezpieczne i jest nieco wolniejsze niż właściwy sposób. Uzyskujesz dostęp do danych QByteArray utworzonych na stosie. Destruktor dla QByteArray można wywołać przed konstruktorem ciągu STL. Najbezpieczniejszy sposób na utworzenie funkcji pomocnika. static inline std::string toUtf8(const QString& s) { QByteArray sUtf8 = s.toUtf8(); return std::string(sUtf8.constData(), sUtf8.size()); }
Vitali
17
@Vitali niepoprawne. „Destruktor dla QByteArray może zostać wywołany przed konstruktorem ciągu STL” jest niepoprawnym stwierdzeniem: Cytując standard: 12.2.3 Obiekty tymczasowe są niszczone jako ostatni krok w ocenie pełnego wyrażenia (1.9), które (leksykalnie) zawiera punkt, w którym zostały utworzone. I pełne wyrażenie, std::string utf8_text = qs.toUtf8().constData();więc twoje stwierdzenie jest niepoprawne
Artem
To prawda - myślałem o const char * x = qs.ToUtf8 (). ConstData (). Czy jednak nie jest łatwiej wywołać qs.toStdString ()?
Vitali,
6
@Vitali Nie. To traci znaki spoza alfabetu łacińskiego1. Spróbuj tego: 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;. Pierwszy jest niepoprawny, drugi jest idealny. Aby to sprawdzić, potrzebujesz terminalu utf8.
Notinlist,
3
Za to, co jest warte, .toStdString()dla mnie zawsze skutkuje naruszeniem dostępu w operatorze potoku, niezależnie od QStringzawartości (innej niż łacińska1). To jest na Qt 4.8.3 / MSVC ++ 10 / Win 7.
Daniel Saner
269

Możesz użyć:

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

Wewnętrznie używa funkcji QString :: toUtf8 () do tworzenia std :: string, więc jest również bezpieczny dla Unicode. Oto dokumentacja referencyjna dla QString.

Pablo Santa Cruz
źródło
73
Począwszy od Qt 5.0, QString::toStdString()teraz używa QString::toUtf8()do konwersji, więc właściwości ciągu znaków Unicode nie zostaną utracone ( qt-project.org/doc/qt-5.0/qtcore/qstring.html#toStdString ).
Emile Cormier
A jeśli chcesz sprawdzić kod źródłowy QString::toStdString, oto on .
thuga
1
Jak mogę sprawdzić, czy rzeczywiście traci właściwość Unicode? Czy wystarczy użycie znaków Unicode (np. Z języka innego niż angielski)?
Yousuf Azad
35

Jeśli Twoim ostatecznym celem jest dostarczenie komunikatów debugujących do konsoli, możesz użyć qDebug () .

Możesz użyć jak

qDebug()<<string;który wydrukuje zawartość do konsoli .

Ten sposób jest lepszy niż konwersja w std::stringcelu debugowania wiadomości.

LIAK
źródło
1
Funkcja qDebug () byłaby znacznie lepsza, ponieważ obsługuje więcej typów Qt.
Kamil Klimek
24
QString qstr;
std::string str = qstr.toStdString();

Jeśli jednak używasz Qt:

QTextStream out(stdout);
out << qstr;
Chris
źródło
Najpierw wypróbowałem << qstr, zanim zapytałem, ale się nie skompilowało. Działa jednak z qstr.toStdString ().
sierpień
2
Nie wydaje mi się Próbowałeś std :: cout << qstr, nie QTextString (stdout) << qstr;
Chris
18

Najlepiej byłoby samemu przeciążyć operatora <<, aby QString można było przekazać jako typ do dowolnej biblioteki oczekującej typu zdolnego do wyjścia.

std::ostream& operator<<(std::ostream& str, const QString& string) {
    return str << string.toStdString();
}
Szczeniak
źródło
3
Dlaczego ludzie głosują w dół? W moim przypadku to przesada, ale kto wie, może być przydatny (dla mnie lub kogoś innego).
sierpień
Podoba mi się to, ponieważ Qt ma nawyk zmieniania sposobu działania ich łańcuchów - i to powoduje konwersję w jednym miejscu.
Den-Jason
12

Alternatywa dla proponowanego:

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

możliwe:

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

Zobacz dokumentację qPrintable , makro dostarczające const char * z QtGlobal.

flokk
źródło
2
działa to nawet z -no-stlzestawem Qt-Build z zestawem -Option. więcej informacji
Senči
8

Najprostszy sposób byłby QString::toStdString().

shaveenk
źródło
2

Możesz tego użyć;

QString data;
data.toStdString().c_str();
Hafsa Elif Özçiftci
źródło
proszę podać szczegóły dotyczące tego, jaki był błąd i dlaczego twoja odpowiedź działa
Anantha Raju C
0
 QString data;
   data.toStdString().c_str();

może nawet zgłosić wyjątek na kompilatorze VS2017 w xstring

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

właściwą drogą (bezpieczna - bez wyjątku) jest to, co wyjaśniono powyżej od Artema

 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();
JPM
źródło
-1

Spróbuj tego:

#include <QDebug>
QString string;
// do things...
qDebug() << "right" << string << std::endl;
wudongliang
źródło
1
Pytanie jest bardzo jasne: przekonwertuj QString na std :: string, aby go nie drukować.
eyllanesc,
@eyllanesc w tekście pytania jest napisane „Jak wyprowadzić zawartość qstring do konsoli?” , wydaje się, że OP zakłada, że ​​konwersja do std :: string jest jedynym sposobem. To naprawdę dwa pytania zadawane jednocześnie.
MM
@MM Pytanie wydaje się niejasne, ponieważ pytanie w tytule mówi: Jak przekonwertować QString na std :: string? , Może to problem XY.
eyllanesc