Partage
  • Partager sur Facebook
  • Partager sur Twitter

caractères accentués et autres dans un fichier txt

trouver les caractères accentués

    9 novembre 2021 à 9:35:02

    Bonjour,

    je suis devant un petit casse tête.

    Comment trouver les caractères accentués et autres dans un fichier texte ?

    Pour le moment avec ce programme je peux trouver les voyelles et les compter.

    #include <iostream>
    #include <fstream>
    #include <unordered_map>
    
    int main()
    {
      std::unordered_map<char, int> nbrLettre{};
      std::ifstream ist("quelques_commandes.txt");
      unsigned char c;
      while (ist >> std::noskipws >> c)
      {
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'y' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'Y')
        {
          nbrLettre [c]++;
        }
      }
      ist.close();
      for (const std::pair<const char, int> e : nbrLettre)
      {
        std::cout << e.first << " -> " << e.second << std::endl;
      }
      return 0;
    }

    Mais comment repérer un "é" ou "è" ou un "ç" ?

    • Partager sur Facebook
    • Partager sur Twitter
      9 novembre 2021 à 9:50:29

      La manière dont est encodé ces caractères est fonction du type d'encodage avec lequel est écrit le fichier texte.

      Comme ces caractères ne fait pas partie de la table ASCII (qui ne contient que 127 caractères, le reste c'est du codepage dépendant), la manière de les écrire sous forme binaire n'est pas standardisée. En plus, si votre code source n'a pas le même codepage que votre fichier lors de la compilation du code source, vous êtes marron.

      Donc, si c'est un exercice, il est mal posé, car ils vous manquent des notions de base pour le "gérer".

      Si c'est un cas concret, il faut restreindre le périmètre de votre bidule.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        9 novembre 2021 à 9:59:30

        Les caractères sont encodés en fr_FR.UTF-8. Je me cantonne au français,

        Je suis sous Ubuntu.

        cette ligne

        std::cout << "Paramètres encodage caractères " << std::locale("").name().c_str() << std::endl;

        renvoie

        Paramètres encodage caractères fr_FR.UTF-8






        -
        Edité par Duncan4031 9 novembre 2021 à 10:06:18

        • Partager sur Facebook
        • Partager sur Twitter
          9 novembre 2021 à 11:38:36

          Dans ce cas il faut tester les caractères avec l'UTF-8. C'est pas très compliqué en soit.

          Tu peux utiliser les fonctions basées sur wchar_t aussi, mais c'est dépendant de la locale (donc si le fichier n'est pas dans la même locale, ça ne fonctionnera pas). Mais normalement toute personne sensée fait de l'UTF-8.

          https://en.wikipedia.org/wiki/UTF-8

          Le début d'une séquence UTF-8 commence par :

          • 110 s'il est composé de 2 octets,
          • 1110 s'il est composé de 3 octets,
          • 11110 s'il est composé de 4 octets.
          • Ensuite chaque octet suivant commenceront par 10 et il faut prendre 6 bits pour chacun

          Avec un peu de manipulations de bits tu n'as plus qu'à découper les entiers comme il faut. 

          Par exemple, le é en unicode est 233, il nécessite donc deux octets :

          • 1100 0011
          • 1010 1001

          En gras, ici notre 233 en binaire découpé selon l'encodage UTF-8. Ainsi mis bout à bout on obtient 00011 101001 qui vaut bien 233.

          Il existe des bibliothèques toutes faites aussi pour faire de la classification, mais parfois c'est de l'usine à gaz pour ce dont on a besoin.

          -
          Edité par markand 9 novembre 2021 à 11:47:05

          • Partager sur Facebook
          • Partager sur Twitter

          l'azerty est aux dispositions ce que subversion est aux SCM

            9 novembre 2021 à 11:38:58

            Ils seront alors sur 2 bytes (pour les caractères accentués du français)

            La version simple, tapes ton code en UTF-8 (le défaut normalement avec tous les éditeurs sur linux; j'en suis bien moins sur pour Windows), et cherche "é". Après on peut avoir des approches plus intelligentes qui cherchent le byte à 0 (IIRC) qui se trouve avant

            • 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.
              9 novembre 2021 à 12:57:21

              D'accord merci je  vais voir tout ça
              • Partager sur Facebook
              • Partager sur Twitter
                9 novembre 2021 à 14:04:35

                Duncan4031 a écrit:

                Les caractères sont encodés en fr_FR.UTF-8. Je me cantonne au français,

                Je suis sous Ubuntu.

                cette ligne

                std::cout << "Paramètres encodage caractères " << std::locale("").name().c_str() << std::endl;

                renvoie

                Paramètres encodage caractères fr_FR.UTF-8

                Attention, ce que tu indiques est l'encodage qui est préconisé si tu utilises la locale courante qui serait donc "fr_FR.UTF_8".
                Mais l'encodage intervient sur plusieurs différentes choses:
                a) quel est l'encodage de tes fichiers sources (ainsi si tu écris auto x = "à"s; comment le compilateur doit comprendre les octets qui décrivent ce 'à' de ton fichier source pendant la compilation.)
                b) quel est l'encodage utilisé par l'application (la chaine précédente mise dans le code va convertir le "à" encodé fichier en un "à" encodé code, la chaine x contient alors la séquence d'octets correspondant dans l'encodage du code.)
                c1) quel est l'encodage du fichier que tu vas lire (au moment de la lecture les octets lus sont convertis pour être mis dans une chaine de caractère au format du code.)
                c2) ou inversement l'encodage d'un fichier qu'on doit écrire (on convertit de l'encodage du code vers l'encodage fichier.)

                Ce que tu as fait ne correspond à aucun des cas ci-dessus. Ça indique que si tu demandes explicitement quelque part à utiliser la locale("") les données seront converties de cette locale vers la locale de ton code, et inversement. Donc tu peux utiliser mon_fichier.imbue(std::locale("")) pour indiquer que le fichier donc être considéré au format UTF_8, mais ce qu'il faudrait faire serait: mon_fichier.imbue(la_locale_effectivement_utilisée_dans_le_fichier). Donc finalement std::locale("") n'est pas vraiment utile dans ton cas!

                Bon, si tu utilises GCC sous Ubuntu, je crois que par défaut pour (a) c'est UTF-8, pour (b) c'est UTF-8. Il ne reste que le format du fichier lui-même et sous LINUX c'est classiquement UTF-8. Ouf, ça simplifie tout (les sources sont UTF-8, le code est UTF-8, la lecture/écriture convertit UTF-8 vers UTF-8 donc ne fait rien!) Sous Windows en remplaçant partout UTF-8 par Windows-1250, ça devrait marcher et serait peut-être plus simple car un caractère accentué tiendrait dans un unique char.

                Ensuite comme en UTF-8 un caractère ne tient pas dans un char. Il faut être prudent dans le code que tu écris. Tu peux:
                - travailler directement en UTF-8, mais tu ne peux pas écrire par exemple if ( mon_car == 'é' ), markand et lmghs t'ont donné le moyen.
                - convertir tes chaines en UTF-16, UTF-32 ou wchar. Ici un char16_t est assez grand pour stocker un caractère accentué. ou même un char32_t pour tolérer des caractères plus particuliers comme le . Mais utiliser les wchar_t est peut-être plus simple. A ce moment le code if ( mon_wchar == L'é') va fonctionner sans problème.
                Pour la seconde méthode, tes chaines sont à gérer sous la forme:

                std::wstring    wtexte;
                std::wifstream  wfile( "monfichier.txt" );
                wfile.imbue(std::locale(std::locale::global(),new std::codecvt_utf8<wchar_t>)); // convertir les UTF-8 du fichier en wchar_t
                std::getline( wfile, wtexte );                       // lire et convertir
                std::wcout << L"La ligne lue est " << wtexte;        // ici on utilise des wchar_t
                for ( wchar_t& x : wtexte ) {
                    if ( x == L'é' )                                 // on teste bien des wchar_t
                        std::cout << "j'ai vu un é dans le fichier"; // ici on utilise des char (vraisemblablement en UTF-8)
                }

                C'est peut être plus facile (mais devient compliqué à chaque fois que tu dois convertir une std::wstring en std::string et inversement.)

                • Partager sur Facebook
                • Partager sur Twitter

                En recherche d'emploi.

                caractères accentués et autres dans un fichier txt

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