• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

klasy Qt vs biblioteka standardowa ( kodownie znaków w obu przypadkach )

0 głosów
89 wizyt
pytanie zadane 12 lipca w C i C++ przez Jakub 0 Stary wyjadacz (13,320 p.)

Witam, kiedyś zadawałem dość podobne pytanie ale teraz skupiam się na nieco innym aspekcie, mam taki kod programu:

#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::string str;
    std::cin >> str;

    std::cout << str << "\n"; //ok
    std::cout << int(str[0]) << "\n"; //ok
    std::cout << char(-91) << "\n"; //ok

    char c = -91;
    qDebug() << c; //?

    QChar qc = -91;
    qDebug() << qc; //??
    qDebug() << qc.unicode(); //?!

    return a.exec();
}

Biorąc pod uwagę kodowanie konsoli windowsowej ( 852 OEM - Latin II) kod litery 'ą' zapisany zapisany w typie char wynosi -91. Wypisanie w ten sposób tej litery daje poprawny wynik:

std::cout << char(-91) << "\n"; //ok

gorzej kiedy chcę wypisać ten sam znak o tym samym kodzie w tym samym typie za pomocą qDebug() :

 char c = -91;
qDebug() << c; //?

dostaje wtedy na ekranie znak Y...

Moje pierwsze pytanie brzmi: Co strumień qDebug() robi z kodem mojego znaku?

Dalej wykorzystując typ QChar jest już całkowita masakra:

przecież to ten sam kod który powinien być przez windowsową konsole tak samo interpretowany. Dla pewności sprawdziłem jeszcze kod litery ą dla typu unsigned char i przypisałem do QChar:

wypisana wartość bzdurna ale chociaż kod liczbowy się zgadza ( czyli QChar przechowuje liczby unsigned )

tak dla ciekawostki, teraz:

unsigned char c = 165;
qDebug() << c; 

będę miał wypisaną nie literę ą ale jej kod czyli 165.

Co więc muszę zrobić żeby wypisać znak używając jego kodu wykorzystując narzędzia z Qt? Nie chodzi mi tu nawet o wyświetlanie polskich znaków w konsoli bo nie ma takiej potrzeby ( Qt to głównie GUI ). Po prostu totalnie nie rozumiem co QChar i qDebug() robi z moim kodem znaku...

z góry dziękuje za pomoc ;)

2 odpowiedzi

0 głosów
odpowiedź 12 lipca przez Bondrusiek Maniak (51,380 p.)

Witam,

jeśli chcesz używać Qt do wyświetlania takich samych wartości jak dla std::cout polecam użyć QTextStream. QTextStream jest strumieniem, który może pobierać bądź zwracać dane. Musisz również ustawić odpowiednie kodowanie ja ustawiłem na UTF-16.

Przykładowy program:

#include <QCoreApplication>
#include <QString>
#include <iostream>
#include <string>
#include <QTextCodec>
#include <QTextStream>


QTextStream _cout(stdout, QIODevice::WriteOnly);

int main (int argc, char **argv) {
    QCoreApplication app(argc, argv);
    //_cout.setCodec("IBM 850");

    _cout.setCodec("UTF-16");


    std::cout << " c++ " << std::endl;
    for(int i = -127; i < 255; ++i)
        std::cout << i << " " << char(i) << std::endl;

    std::cout << " qt " << std::endl;
    for(int i = -127; i < 255; ++i)
        _cout << i << " " << QChar(i) << endl;

    return app.exec();
}

 

komentarz 12 lipca przez j23 VIP (105,900 p.)
Coś mi się wydaje, że to nie wyświetli poprawnie tekstu w kodowaniu cp852 (bo jeśli dobrze zrozumiałem OP, o to mu chodzi).
komentarz 12 lipca przez Jakub 0 Stary wyjadacz (13,320 p.)

@Bondrusiek

Nie do końca poprawnie działa:

#include <QCoreApplication>
#include <QString>
#include <iostream>
#include <string>
#include <QTextCodec>
#include <QTextStream>


QTextStream _cout(stdout, QIODevice::WriteOnly);
QTextStream _cin(stdin, QIODevice::ReadOnly);

int main (int argc, char **argv) {
    QCoreApplication app(argc, argv);

    _cout.setCodec("IBM 850"); //cp852

    _cout << QChar(165) << endl; // ą
    QChar a;
    _cin >> a;
    _cout << a << endl;
    _cout << a.unicode() << endl;

    return app.exec();
}

W kodowaniu cp852 165 to znak 'ą', a tu wypisuje się 'ż'. Dla kodowania UTF-16 wypisywanie działa dobrze ale gorzej kiedy próbujemy wypisać znaki wczytane z klawiatury ( raz jest okej a raz głupota w zależności od znaku ).  Zrobiłem jeszcze tak:

_cin.setCodec("IBM 850");

ale efekt jest bzdurny:

*I tu jeszcze małe pytanie, dlaczego wypisując liczbę 209 mamy przerwy między cyframi??

komentarz 12 lipca przez Bondrusiek Maniak (51,380 p.)

@Jakub 0

*I tu jeszcze małe pytanie, dlaczego wypisując liczbę 209 mamy przerwy między cyframi??

Tak na pierwszy rzut oka nie wiem. Wydaje mi się powinieneś przeszukać dokumentacje klasy QTextStream: https://doc.qt.io/qt-5/qtextstream.html i znaleźć funkcje, która modyfikuje strumień. Pewnie rozpoczyna się na set...

komentarz 12 lipca przez Jakub 0 Stary wyjadacz (13,320 p.)
Poszukam sobie...

Ale zastanawiam się czy najlepszym sposobem na mój problem nie będzie po prostu konwersja z QChar na unsigned char i używanie standardowych strumieni w C++...

myślisz że tak ujdzie czy mało profesjonalnie?

* wiem że typ QChar jest bardziej pojemny, ale do polskich znaków char wystarczy.
komentarz 12 lipca przez Bondrusiek Maniak (51,380 p.)
Wydaje mi się że to dobry pomysł unsigned char przechowuje wartość od 0 do 255.
0 głosów
odpowiedź 12 lipca przez mokrowski VIP (111,160 p.)

Dla VS:

https://docs.microsoft.com/en-us/cpp/build/reference/execution-charset-set-execution-character-set?view=vs-2019

Jeszcze jest (nie wiem czy udokumentowana) pragma dla VS:

#pragma execution_character_set("utf-8") // Tu podstaw co tam chcesz ale nie daję głowy że będzie zawsze działać.

Dla gcc:

https://gcc.gnu.org/onlinedocs/cpp/Invocation.html opcje:

-finput-charset, -fexec-charset i -fwide-exec-charset

 

Poza tym od Win 7 (którejś rewizji), cmd obsługuje już kodowanie utf-8: https://stackoverflow.com/questions/388490/how-to-use-unicode-characters-in-windows-command-line/388500#388500 więc może nie kop się z koniem :)

Podobne pytania

0 głosów
1 odpowiedź 54 wizyt
0 głosów
0 odpowiedzi 123 wizyt
Porady nie od parady
Publikując kody źródłowe korzystaj ze specjalnego bloczku koloryzującego składnię (przycisk z napisem code w edytorze). Nie zapomnij o ustawieniu odpowiedniego języka z rozwijanego menu oraz czytelnym formatowaniu kodu.Przycisk code

65,794 zapytań

112,440 odpowiedzi

237,547 komentarzy

46,729 pasjonatów

Przeglądających: 231
Pasjonatów: 11 Gości: 220

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...