Fonction qui capture un caractere dans un fichier [Résolu]

Signaler
-
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
-
Bonjour,
Je souhaite lire les caractères dans un fichier un par un puis copier ces caractères dans une variable afin de les comparer et au final de déterminer quel caractère à été le plus utilisé.
Cependant, dans mon code je n'arrive pas à utiliser la fonction getc afin de "capturer les caractères du fichier...

Je vous remercie par avance pour votre aide.
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <limits>



int main()
{
    std::string tablettre = {'a', 'b', 'c', 'd', 'e', 'f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    int tabchiffre[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    std::string filename;

        std::cout << "Quel est le nom de l'adresse ou se trouve le fichier ?" << std::endl;
        std::getline(std::cin, filename);                                                     //Acquisition de l'adresse du fichier

        std::ifstream file(filename);
        if (!file)
        {
            std::cerr << "Fichier non trouvé: " << filename << std::endl;                     //cas ou le fichier n'existe pas ou l'adresse n'est pas bonne
            return 1;
        }
        int i;
        char caractere;
        while(std::getc(file))
        {
         caractere = std::getc(file);
              for (i = 0; i < 26; i++)
              {
                if(tablettre[i] == caractere)
                {
                tabchiffre[i]++;
                }
              }
        }
        int leplusgrand = tabchiffre[0];
        for (i = 1; i < 26; i++){
            if(tabchiffre[i] > tabchiffre[i-1]){
                leplusgrand = tabchiffre[i];
            }
        }
        std::cout << "La lettre qui a la plus grande frequence dans le message est la lettre : " << tablettre[leplusgrand] << std::endl;
        int key;
        key = -5 + leplusgrand;
        if(key > -1)
            std::cout << "le key number est donc egal a : " << key << std::endl;
        else
            std::cout << "le key number est donc egal a : " << 26 + key << std::endl;

    return 0;
}

3 réponses

Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Bonjour !

Quelques soucis:
  • Tu peux écrire: std::string tablettre = "abcdef...";
  • int tabchiffre[26] peut s'initialiser avec {0}
  • Pour récupérer un fichier: file.get(c)
  • Pas besoin de tablettre, ni de boucler pour chercher une lettre. Un caractère ascii est un nombre ! 'a' et 97, c'est pareil ! Donc l'index 0 de ton tableau, c'est 97 - 97 ou 'a' - 'a'. Pour l'index 1, il faut faire 'b' - 'a', etc... Donc tu as la formule tabchiffre[caractères - 'a'] pour incrémenter la valeur d’occurrences d'une lettre.
  • Pour trouver le plus grand d'un tableau, retient l'index, pas la valeur du tableau.
  • Déclare une variable au moment de l'utiliser pas tout en haut d'une fonction. Plus tu limites la "visibilité" d'une variable, mieux c'est. Pareil, une variable d'index (i) au sein d'une boucle ne devrait exister que dans cette boucle. Donc écrit généralement "for (int i = 0; ...", de manière à ce que i soit limité à cette boucle.


Voici une correction propre, de ce que tu as proposé:
#include <iostream>
#include <string>
#include <fstream>

int main()
{
    std::cout << "Quel est le nom de l'adresse ou se trouve le fichier ?" << std::endl;
    std::string filename;
    std::getline(std::cin, filename);

    std::ifstream file(filename);
    if (!file)
    {
        std::cerr << "Fichier non trouvé: " << filename << std::endl;
        return 1;
    }

    int tabchiffre[26] = {0}; // initialise tous les éléments à 0.
    char caractere;
    while (file.get(caractere))
    {
        if (caractere >= 'a' && caractere <= 'z')
        {
            tabchiffre[caractere - 'a']++;
        }
    }

    int leplusgrand = 0;
    for (int c = 1; c < 26; ++c)
    {
        if (tabchiffre[c] > tabchiffre[leplusgrand])
        {
            leplusgrand = c;
        }
    }
    std::cout << "La lettre qui a la plus grande frequence dans le message est la lettre : "
              << char('a' + leplusgrand) << " avec " << tabchiffre[leplusgrand] << std::endl;

    return 0;
}
Merci beaucoup pour votre aide et votre réactivité!
Je prends bonne note de tous vos conseils, pour les variables à déclarer au moment de les utiliser, c'est pour éviter de monopoliser de la mémoire? ou peut être que la raison est différente...
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Pour les variables à utiliser au bon moment, c'est pour le scoping (la portée) comme je l'ai écrit dans le message précédent. Il n'y a aucune différence de performance ou de mémoire.

Exemple:
int i = 0;
for (i = 0; i < nb; i++)
{
  std::cout << i << std::endl; //  existe ici;
}
std::cout << i << std::endl; // i existe ici

for (int i = 0; i < nb; i++)
{
  std::cout << i << std::endl; //  existe ici;
}
std::cout << i << std::endl; // i n'existe pas ici


Plus tu limite tes scopes, moins tu as de chance de réutiliser des variables par inadvertance. Ici c'est un exemple simple, mais tu te doutes bien que dans un code plus conséquent, c'est source d'erreurs. Une bonne habitude à prendre dès maintenant.

En plus de cela, c'est bien plus lisible. S'il faut aller chercher 10km plus haut dans le code à quoi correspond une variable, c'est moins pratique. Jouer sur les "const" et les "{ }" (scoping), c'est la base d'un code bien carré, lisible et "safe".