Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème utilisation UTF-8 sous Windows

    20 février 2024 à 16:34:25

    Bonjour, j'ai récemment recommencé à apprendre le c++ grâce au formidable cours sur ZesteDeSavoir. Je suis actuellement sur le chapitre qui concerne l'utilisation des fichiers extérieurs, et un détail me titille : lorsque l'on nous explique comment utiliser l'UTF-8 sous Windows. Je me disais au début que au final j'en avais un peu rien à faire et que l'ASCII me convenais parfaitement, j'avais juste à ne pas utiliser d'accents et autres fantaisies. Mais j'ai quand même essayé d'ouvrir un fichier texte avec de l'UTF-8, car "on sait jamais". J'ai donc tout simplement recopié le code exemple fournis dans le cours et suivis les indication d'enregistrement du code source. Mais quand je compile, une horrible erreur... 

    Je n'ai absolument aucune idée de où cela peut venir.

    J'espère trouver un peu d'aide dans ce forum..

    • Partager sur Facebook
    • Partager sur Twitter
      20 février 2024 à 17:13:15

      Salut,


      Copie-colle code et erreur avec le bouton </> qui va bien. Evite les screenshoots si tu veux maximiser nos chances de regarder ce qui t'arrive.

      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        20 février 2024 à 23:07:10

        Pour avoir une idée d'où ça vient, il faudrait prendre la peine de lire les messages. C'est à ça qu'ils servent.

        Et pour ça, les faire défiler un peu latéralement, parce que ça  déborde à droite.

        -
        Edité par michelbillaud 20 février 2024 à 23:09:03

        • Partager sur Facebook
        • Partager sur Twitter
          20 février 2024 à 23:34:08

          FélixCabanel2 a écrit:

          une horrible erreur... 

          J'ai du chercher, je comprenais pas non plus d'où venait l'erreur.

          Si tu compiles en utilisant le C++17 (le code a été publié en 2018), cela fonctionne correctement.

          Dans le C++20, le u8 ont été changé de "const char[N]" en "const char8_t[N]" https://en.cppreference.com/w/cpp/language/string_literal. Ces char8_t ne sont pas compatible avec std::string (pour rappel, std::string est un alias du type std::basic_string<char>). Il faut utiliser std::u8string (qui est un alias du type std::basic_string<char8_t>)

          Le but est de forcer à ne pas mélanger des char et des char UTF8 et éviter que de l'UTF8 soit manipulé comme de l'ASCII.

          Le problème est que tous les manipulateurs de string doivent aussi utiliser char8_t, et donc tu peux pas utiliser directement std::cout ou std::ofstream. Il y a des hacks, mais c'est très moche.

          Honnêtement, t’embête  pas trop avec ca, le support de l'UTF8 est moisi en C++ (sans lib) et c'est une perte de temps.

          -
          Edité par gbdivers 20 février 2024 à 23:35:16

          • Partager sur Facebook
          • Partager sur Twitter
            21 février 2024 à 9:15:37

            Pour ceux qui voulais voir l'erreur complète, je vous la met dans le prochain message, mais je pense que gbdivers à tout de même trouvé le coeur du problème. En effet lorsque je change les "std::string" par des "std::u8string", l'erreur concernant le std::vector disparait, en revanche il est vrais que je ne peux pas inclure le texte UTF-8 dans mon fichier texte avec std::ofstream ... 

            C'est pas grave, je vais devoir me résoudre à ne pas utiliser d'UTF-8 et de rester sur le ASCII.

            Build started...

            1>------ Build started: Project: TestCpp, Configuration: Debug x64 ------

            1>main.cpp

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): error C2440: 'initializing': cannot convert from 'initializer list' to 'std::vector<std::string,std::allocator<std::string>>'

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : 'std::vector<std::string,std::allocator<std::string>>::vector(std::initializer_list<_Ty>,const _Alloc &)': cannot convert argument 1 from 'initializer list' to 'std::initializer_list<_Ty>'

            1>        with

            1>        [

            1>            _Ty=std::string,

            1>            _Alloc=std::allocator<std::string>

            1>        ]

            1>        and

            1>        [

            1>            _Ty=std::string

            1>        ]

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : Element '1': no conversion from 'const char8_t [25]' to '_Ty'

            1>        with

            1>        [

            1>            _Ty=std::string

            1>        ]

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : Element '2': no conversion from 'const char8_t [44]' to '_Ty'

            1>        with

            1>        [

            1>            _Ty=std::string

            1>        ]

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : Element '3': no conversion from 'const char8_t [30]' to '_Ty'

            1>        with

            1>        [

            1>            _Ty=std::string

            1>        ]

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : Element '4': no conversion from 'const char8_t [29]' to '_Ty'

            1>        with

            1>        [

            1>            _Ty=std::string

            1>        ]

            1>C:\Users\felix.cabanel\OneDrive - ESTIA\Bureau\Cours ZesteDeSavoir\TestCpp\TestCpp\main.cpp(9,5): message : while trying to match the argument list '(initializer list)'

            1>Done building project "TestCpp.vcxproj" -- FAILED.

            ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

            ========== Build started at 09:08 and took 00,733 seconds ==========

            -
            Edité par FélixCabanel2 21 février 2024 à 9:16:10

            • Partager sur Facebook
            • Partager sur Twitter
              21 février 2024 à 10:49:45

              L'UTF-16 est ton ami.
              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                21 février 2024 à 16:58:23

                C'est pas vraiment de l'ASCII, dans la console windows c'est une extension 8 bits de l'ASCII qui n'en comporte que 7.

                Définie par un "code page", genre 850  OEM Multilingue Latin 1 ; Europe occidentale (DOS), qui va donner la correspondance entre les codes 8 bits et les petits gribouillis à afficher (en passant par leur expression graphique par une police)

                https://learn.microsoft.com/fr-fr/windows/win32/intl/code-page-identifiers

                 Par ailleurs MS est coincé entre

                • son usage historique des jeux de caractères 8 bits hérités de DOS (qui lui même les tenait d'IBM)
                • son idée géniale de prétendre faire de l'Unicode sur des "caractères larges" 16 bits (UCS-2, windows 95 et NT 3.1, abandonné depuis), puis UTF-16 (1 ou 2 mots de 16 bits, windows 2000).  Autant dire la compatibilité avec le reste du monde (UTF-8) ça traîne des pieds.

                ----

                Les spécialistes de C++ ont oublié une piste simple : surcharger << pour afficher les u8string

                #include <iostream>
                #include <string>
                #include <vector>
                
                using namespace std;
                
                std::ostream & operator<<(std::ostream & out,
                                          const std::u8string &string)
                {
                    for(auto c : string) {
                        out << (char) c;
                    }
                    return out;
                }
                
                void test1() {
                   std::u8string chaine { u8"Test réussi !"};
                   std::cout << chaine << std::endl;
                }
                
                int main()
                {
                    // test1();
                    std::vector<std::u8string> const phrases {
                        u8"Bonjour",
                        u8"你好",
                        u8"Здорово",
                        u8"おはようございます"
                    };
                
                    for (auto &phrase : phrases) {
                        std::cout << phrase << std::endl;
                    }
                }

                Compilation et exécution sous Linux (console en UTF-8)

                $ clang++ -std=c++20 -Wall -Wextra -pedantic -Werror -Wno-unused -g    prog.cc   -o prog
                $ ./prog
                Bonjour
                你好
                Здорово
                おはようございます


                En vrai, il faudrait detecter l'encodage choisi pour le ostream, et en fonction de ça faire la conversion UTF8 -> le truc qui va bien.




                -
                Edité par michelbillaud 22 février 2024 à 14:51:28

                • Partager sur Facebook
                • Partager sur Twitter

                Problème utilisation UTF-8 sous Windows

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                • Editeur
                • Markdown