Fonction qui capture un caractere dans un fichier

Résolu
GrGrGr - Modifié le 14 févr. 2021 à 20:28
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 16 févr. 2021 à 17:47
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

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 14 févr. 2021 à 22:07
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;
}
1
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...
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
Modifié le 16 févr. 2021 à 17:47
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".
0
Rejoignez-nous