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?

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


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.


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.


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;

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

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.


2
działa to nawet z -no-stlzestawem Qt-Build z zestawem -Option. więcej informacji
Senči



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

-1

Spróbuj tego:

#include <QDebug>
QString string;
// do things...
qDebug() << "right" << string << std::endl;

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.