Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.4.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

[Qt4] QString toUpper

December 2006 modifié dans Année 2006
Bonjour,

Je travail sur un projet sous Windows XP avec Qt 4.2.2 et je tente de faire une conversion de texte en majuscule avec la fonction toUpper de QString et j'obtient quelque erreur de conversion dont je ne trouve pas le problème. En effet bien que la plus part des caractères soit correctement mis en majsucule, certains sont remplacé par un ?. Exemple:

Cabron émeri carré - gr. 0 / 30µ;SIA / Dimensions : 8 x 8 mm

devient

CABRON ÉMERI CARRÉ - GR. 0 / 30?;SIA / DIMENSIONS : 8 X 8 MM

On peut voir que le caractère µ n'est pas conservé

Alors qu'un caractère tel que Ø est correctement conservé.

Jean-Luc

Réponses

  • j'ai fait une fonction permettant de contrer cela, même si c'est vraiment moche:


    QString patchUpper(QString text_org, QString text_upp)
    {
    QString textNew;

    for(int i=0; i<text_org.length(); i++)
    {
    QChar c_org = text_org.at(i);
    QChar c_upp = text_upp.at(i);
    if(c_org.isLetter())
    {
    if(c_org.isUpper())
    textNew += c_upp;
    else
    {
    if(c_org == c_upp.toLower())
    textNew += c_upp;
    else
    textNew += c_org;
    }
    }
    else
    {
    textNew += c_org;
    }
    }

    return textNew;
    }

    QString t1 = "fdsfds Ø ö é $à 30µ;SIA / D";
    QString t2 = t1.toUpper();


    qDebug(patchUpper(t1,t2));
  • Tout d'abord de quel « µ » s'agit-il ? Du symbole pour micro ou de la lettre grecque ? Car la lettre grecque μ a bien pour majuscule Μ tandis que le symbole pour micro n'a pas de majuscule.
  • December 2006 modifié
    J'ai créé le fichier encodé en UTF-8 attaché en pièce jointe.

    Ce fichier contient la lettre grecque μ (0xcebc) et le symbole µ pour micro (0xc2b5). Si je le lis dans examples/mainwindows/application les lettres s'affichent bien en miniscules. Si je modifie le programme en changeant la ligne suivnate de mainwindow.cpp
    textEdit->setPlainText(in.readAll());
    en
    textEdit->setPlainText(in.readAll().toUpper());
    les deux lettres sont afichées en majuscules.

    J'ai fait ça sous Linux mais je soupçonne que c'est pareil sous Windows.

    Bref, je n'arrive pas à reproduire le problème. Comment le reproduire ?

    Décidement, les pièces jointes ce n'est pas ça sur ce forum. Voici le fichier en question :
    MICRO : µ
    MU : μ
  • [MODE Hors-sujet]
    dimitri said:
    Décidement, les pièces jointes ce n'est pas ça sur ce forum. Voici le fichier en question :
    J'y travaille dès que j'ai le net à la maison...
    [/MODE Hors-sujet]
  • Voilà, le problème vient du faite que je dois écrire l'info dans un fichier texte. Effectivement en utilisant uniquement des widgets comme un QLabel ou un QLineEdit, il n'a pas de problème. J'obtient aussi le M pour le caractère µ donc la lettre greque.

    TOTO Ø Ö É $À 30Μ;SIA / D

    Par contre, pour écrire dans un fichier je passe par un toLatin1() et le problème ce crée à ce moment là. Voilà un exemple de code:

    #include
    #include
    #include

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QFile f("c:/debug.txt");

    QString s("toto Ø ö é $à 30µ;SIA / D");

    f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);

    f.write(s.toUpper().toLatin1(), s.length());

    f.close();

    QLabel label(s.toUpper());

    label.show();

    return app.exec();
    }

    résultat dans le fichier: TOTO Ø Ö É $À 30?;SIA / D

    Donc, dans l'affichage du label tout est ok mais pas dans l'écriture du fichier text.
    Est-ce que je fais une erreur ?!? Y'a-t-il un autre moyen d'écrire dans un fichier texte qu'avec toLaint1()?
    J'obtient le même résultat en passant par QTextStream .


    ...

    QString s("toto Ø ö é $à 30µ;SIA / D");

    f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);

    QTextStream in(&f);

    in << s.toUpper();

    f.close();

    ...
  • letux said:
    Est-ce que je fais une erreur ?!? Y'a-t-il un autre moyen d'écrire dans un fichier texte qu'avec toLaint1()?
    Il n'est pas nécessaire d'utiliser toLatin1() pour écrire dans un fichier, on peut aussi utiliser toLocal8Bit (), toUtf8(), toUcs4(), utf16(), etc. Tout dépend de l'encodage souhaité dans le fichier.

    De plus utiliser toLatin1() enlève tous les caractères qui ne sont pas ISO-8859-1. Or ISO-8859-1 comprend bien le µ qui représente le symbole « micro » mais pas le μ de l'alphabet grec - ce sont deux caractères Unicode distincts. Je soupçonne que c'est le μ de l'alphabet grec qui était utilisé dans ce cas précis.
  • Suite...

    Petit Bug (je pense):

    D'habitude, je fait un toUpper avant le changement d'encodage, et là j'ai inversé. En faisant ainsi, l'application crash à ligne in << s.toLocal8Bit().toUpper(); alors que si je fait in << s.toUpper().toLocal8Bit() y'a pas de problème. Je suis sous windows XP service pack2 avec Qt 4.2.2

    f.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);

    QTextStream in(&f);
    in << s.toLocal8Bit().toUpper();

    f.close();

    Bref ce n'est pas là que je voulais en venir. J'ai bien tenté les différentes fonctions citées mais je n'arrive pas à régler mon problème avec ce caractère grecque et comme je n'ai pour le moment plus temps de chercher plus loin je reste avec ma moche de fonction :-).

    Merci à Dimitri pour son aide très appréciée.
  • letux said:
    D'habitude, je fait un toUpper avant le changement d'encodage, et là j'ai inversé. En faisant ainsi, l'application crash à ligne in << s.toLocal8Bit().toUpper(); alors que si je fait in << s.toUpper().toLocal8Bit() y'a pas de problème. Je suis sous windows XP service pack2 avec Qt 4.2.2</div>
    Bien vu ! Certes, si s est un QString, alors s.toLocal8Bit() est un QByteArray pas forcément encodé en Latin-1, tandis que QByteArray::toUpper() attend forcément du Latin-1. Donc c'est peut-être une mauvaise idée d'utiliser les fonctions dans cet ordre... mais ça ne devrait pas planter ! Le code suivant plante sous Valgrind :
    #include <QApplication>
    int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QString s(0x03bc); // greek small letter mu
    QByteArray b = s.toLocal8Bit();
    QByteArray u = b.toUpper();
    }
    avec le message d'erreur suivant :
    [...]
    ==18841== Memcheck, a memory error detector.
    [...]
    ==18841== Invalid read of size 2
    ==18841== at 0x5177544: qGetProp(unsigned) (qunicodetables.cpp:21)
    ==18841== by 0x51777C3: QUnicodeTables::upper(unsigned) (qunicodetables.cpp:85)
    ==18841== by 0x510F8EE: QByteArray::toUpper() const (qbytearray.cpp:2450)
    ==18841== by 0x80498A7: main (bar.cpp:6)
    [...]
    J'envoie donc un rapport de bug à Trolltech...
    letux said:
    Bref ce n'est pas là que je voulais en venir. J'ai bien tenté les différentes fonctions citées mais je n'arrive pas à régler mon problème avec ce caractère grecque et comme je n'ai pour le moment plus temps de chercher plus loin je reste avec ma moche de fonction :-).
    Je ne comprends pas, ceci marche très bien pour écrire dans un fichier encodé en UTF-8 :
    #include <QString>
    #include <stdio.h>
    int main() {
    QChar c(0x03bc); // greek small letter mu
    QString s(c);
    QString u(s.toUpper());
    printf("%s -> %s\n", s.toUtf8().data(), u.toUtf8().data());
    }
    Le résultat sous Linux avec une locale UTF-8 est :
    μ -> Μ
  • dimitri said:
    J'envoie donc un rapport de bug à Trolltech...
    En fait je crois que le bug est déjà corrigé dans la version de développement de Qt.
  • Je suis d'accord sur le fait que pour un fichier encodé en UTF8 il n'y est pas de problème. Seulement, je doit écrire dans des fichiers textes qui sont relut par une ancienne application qui elle ne lit pas les fichier en utf8, d'oû le problème.
  • letux said:
    Je suis d'accord sur le fait que pour un fichier encodé en UTF8 il n'y est pas de problème. Seulement, je doit écrire dans des fichiers textes qui sont relut par une ancienne application qui elle ne lit pas les fichier en utf8, d'oû le problème.
    Pas de problème, c'est possible aussi. Quel est l'encodage utilisé par cette ancienne application ?
Connectez-vous ou Inscrivez-vous pour répondre.