IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Recherche de voyelles dans un fichier


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut Recherche de voyelles dans un fichier
    Bonjour a tous

    Pourquoi mon code ne trouve pas tout les voyelles qui se trouve dans mon texte ?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
       1. #include  <stdlib.h>
       2. #include <stdio.h>
       3. #define TAILLE_MAX 1000
       4.
       5.
       6. int main(int argc, char *argv[])
       7. {
       8.
       9. char voy[6] = {'a','e','i','o','u','y'};
      10. int compte[6] = {0}, i;
      11. FILE* fichier = NULL;
      12. char chaine[TAILLE_MAX] = "";
      13.
      14.    if ((fichier = fopen("test.txt", "r" )) != NULL)
      15. {
      16.          while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
      17.           {
      18.              for(i = 0; i < 6; i++)
      19.              if(chaine[i] == voy[i])
      20.              compte[i] = compte[i] + 1; // On affiche la chaîne qu'on vient de lire
      21.           }
      22.
      23.     printf("Votre texte comporte :\n" );
      24.     for(i = 0; i < 6; i++)
      25.     printf("%d fois la lettre %c\n", compte[i], voy[i]);
      26.
      27.     fclose(fichier);
      28. }
      29.
      30.   return 0;
      31. }

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    Le problème vient du fait que tu utilise le mauvais indice pour parcourir la chaine et/ou le tableau de voyelles.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      18.              for(i = 0; i < 6; i++)
      19.              if(chaine[i] == voy[i])
      20.              compte[i] = compte[i] + 1;

    ici tu fais:

    0) lecture ligne
    1) chaine[0] == voy[0] ?
    2) chaine[1] == voy[1] ?
    ...
    6) chaine[5] == voy[5] ?
    7) lecture d'une autre ligne

    Alors qu'une solution serait de faire:

    Pour chaque caractère de la chaîne on test toutes les voyelles.

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
    {
    	//calcule la longueur de la  chaine
    	size_t longueur_chaine = strlen(chaine);
     
    	//pour chaque caractère de la chaine
    	for(i = 0; i < longueur_chaine; i++)
    	{
    		//pour chacune des voyelles
    		for(j = 0; j < sizeof(voy); j++)
    		{
    			//test si le caractère courant vaut une des voyelles
    			if(chaine[i] == voy[j])
    				compte[j]++;
    		}
    	}
    }

    Il faut donc deux indices:

    i: indice du caractère courant de la chaine
    j: indice dans le tableau de voyelles

    Il existe surement des solutions plus efficaces (ou tout du moins plus courte) avec des fonctions C spécifiques. Je pense à strtok(), strpbrk() ou encore strcspn(), etc.

    P.S: fait attention à l'indentation et au bloc de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      18.              for(i = 0; i < 6; i++)
      19.              if(chaine[i] == voy[i])
      20.              compte[i] = compte[i] + 1;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                   for(i = 0; i < 6; i++)
                   {
                       if(chaine[i] == voy[i])
                           compte[i] = compte[i] + 1;
                   }

  3. #3
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Parce qu'il faut tester chaque caractère du fichier, là tu parcours le fichier ligne par ligne (si effectivement une ligne ne dépasse jamais TAILLE_MAX caractères), et tu ne testes pas chaque caractère de chaque ligne. Tu as deux options :

    - Parcourir le fichier avec fgetc et tester chaque caractère (la solution que je recommande)
    - Parcourir le fichier avec fgets et tester chaque caractère de chaque chaîne retournée. C'est-à-dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
    {
        for(i = 0; chaine[i] != '\0'; i++) // Pour chaque caractère de chaine ...
        {
            int j;
            for(j = 0; j < 6; j++) // ... tester si c'est une voyelle
            {
                if (chaine[i] == voy[j])
                    compte[j] = compte[j] + 1;
            }
        }
    }

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut
    Ok merci a vous

    1 / Au lieu de mettre longueur_chaine dans for(i = 0; i < longueur_chaine; i++) je peut mettre TAILLE_MAX ?

    2/ Juste pour comprendre.. dans mon 1er code ( là ou se trouve l'erreur) j'ai :

    lecture de la 1er ligne

    chaine[0] == voy[0]
    chaine[1] == voy[1]
    ...
    chaine[5] == voy[5]

    mais à la lecture de la 2eme ligne la valeur de i revient à 0 ? (car a la fin de la lecture de la 1ere ligne i =5)

  5. #5
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par lassault1 Voir le message
    1 / Au lieu de mettre longueur_chaine dans for(i = 0; i < longueur_chaine; i++) je peut mettre TAILLE_MAX ?
    Non. D'une part, parce que fgets stoppe la lecture dès qu'une ligne complète a été lue, pas lorsque le buffer (ici chaine) est plein (sauf si la ligne est trop longue pour être lue d'un seul coup), or la longueur d'une ligne est variable dans un fichier. Il calculer la longueur de chaque ligne avec strlen. De plus, si la taille du buffer que tu utilises dans fgets est TAILLE_MAX, la longueur max d'une ligne, si on veut à chaque fgets lire une ligne complète, doit donc être TAILLE_MAX - 1 et non TAILLE_MAX. En effet, il faut toujours avoir de la place pour le '\0' final.

    mais à la lecture de la 2eme ligne la valeur de i revient à 0 ?
    Non. i revient à 0 après le i = 0 dans for(i = 0; ...). En conclusion, en effet, i revient à 0 à chaque itération.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut
    Ok merci..

    Il y a un truc bête que je comprend pas..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     for(i = 0; i < 6; i++) 
            {
               // instructions
            }
    Dans cette boucle, a la fin de l'instruction de la 1ere boucle i = 1 car il a été incrémenter, mais lorsqu'il fait la 2eme boucle il va lire i = 0. Alors pourquoi i = 1 ??

    PS: Neitsa a mit sizeof(voy) dans for(j = 0; j < sizeof(voy); j++) car voy est de type char.. si ça serait un tableau de type int ça serait faux de faire comme il a fait si j'ai bien compris ?

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Dans cette boucle, a la fin de l'instruction de la 1ere boucle i = 1 car il a été incrémenter, mais lorsqu'il fait la 2eme boucle il va lire i = 0. Alors pourquoi i = 1 ??
    Tu n'as toujours pas compris le fonctionnement de for ? Dans ce cas je ne vois qu'une seule solution : [Tutoriel] L'instruction for.

    Neitsa a mit sizeof(voy) dans for(j = 0; j < sizeof(voy); j++) car voy est de type char.. si ça serait un tableau de type int ça serait faux de faire comme il a fait si j'ai bien compris ?
    voy n'est pas de type char. C'est, génériquement, un tableau de char et, plus précisément, un tableau de 6 char. Puisque sizeof(char), par définition même, vaut 1, il est inutile d'écrire sizeof(voy) / sizeof(char). Si voy était un tableau de int, il fallait effectivement écrire sizeof(voy) / sizeof(int). Une autre manière de faire et souvent recommandée est tout simplement d'écrire sizeof(voy) / sizeof(voy[0]).

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut
    Merci a vous.. résolu

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
    {
    	//calcule la longueur de la  chaine
    	size_t longueur_chaine = strlen(chaine);
     
    	//pour chaque caractère de la chaine
    	for(i = 0; i < longueur_chaine; i++)
    	{
    		//pour chacune des voyelles
    		for(j = 0; j < sizeof(voy); j++)
    		{
    			//test si le caractère courant vaut une des voyelles
    			if(chaine[i] == voy[j])
    				compte[j]++;
    		}
    	}
    }
    Pourquoi pas avoir mis tout simplement for(i = 0; i < sizeof(chaine); i++) au lieu de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    size_t longueur_chaine = strlen(chaine);
     
    for(i = 0; i < longueur_chaine; i++)

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    donne la taille du tableau et non de la chaine.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 103
    Points : 44
    Points
    44
    Par défaut
    Merci jeroman

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WinXP] rechercher du texte dans les fichiers
    Par arcane dans le forum Windows XP
    Réponses: 3
    Dernier message: 05/05/2006, 12h10
  2. Réponses: 7
    Dernier message: 21/02/2006, 17h43
  3. [Configuration] recherche de texte dans un fichier
    Par carlos20 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 10
    Dernier message: 17/10/2005, 17h25
  4. Rechercher liens href dans un fichier
    Par ribrok dans le forum Langage
    Réponses: 5
    Dernier message: 27/09/2005, 17h15
  5. recherche de doublons dans un fichier texte
    Par portu dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 07/10/2003, 14h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo