Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1836 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Recherche de voyelles dans un fichier

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Recherche de voyelles dans un fichier

n°1985066
lassault1
Posté le 17-04-2010 à 13:18:50  profilanswer
 

Bonjour a tous  :)  
 
Pourquoi mon code ne trouve pas tout les voyelles qui se trouve dans mon texte ?
 

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

mood
Publicité
Posté le 17-04-2010 à 13:18:50  profilanswer
 

n°1985086
Un Program​meur
Posté le 17-04-2010 à 15:28:05  profilanswer
 

- tu ne regardes que les 6 premiers caractères de chaque ligne lue
- tu ne compares chacun de ces caractères qu'avec une seule voyelle
 
En prime,
- les constantes magiques comme 6, c'est mal
- l'indentation aléatoire


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1985091
lassault1
Posté le 17-04-2010 à 15:44:45  profilanswer
 

Je dois faire quoi pour l'arranger?

n°1985095
Un Program​meur
Posté le 17-04-2010 à 15:53:41  profilanswer
 

- regarder chaque caractère de tes lignes
- les comparer avec toutes les voyelles
- définir un nom symbolique et l'utiliser à la place de 6
- indenter correctement


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1985096
gilou
Modérateur
Modzilla
Posté le 17-04-2010 à 15:55:17  profilanswer
 

Quand tu fais
for(i = 0; i < 6; i++)
    if(chaine[i] == voy[i])
tu testes seulement si le i-eme caractère de la chaine est la i-eme voyelle au lieu de tester si chaque caractère de la chaine est la i-me voyelle.

 

En modifiant un peu ton code ceci marche:

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

Une version un peu plus évoluée, qui teste aussi les majuscules:

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define TAILLE_MAX 1000
  5. int main(int argc, char *argv[])
  6. {
  7.   char voy[12] = {'a', 'e', 'i', 'o', 'u', 'y',
  8.                   'A', 'E', 'I', 'O', 'U', 'Y'};
  9.  
  10.   int compte[6] = {0};
  11.   char buffer[TAILLE_MAX];
  12.   FILE* fichier = fopen("test.txt", "r" );
  13.   int i, j, lgchaine;
  14.   if (!fichier) {
  15.     printf("Cannot open text.txt\n" );
  16.     return EXIT_FAILURE;
  17.   }
  18.   while (fgets(buffer, TAILLE_MAX, fichier)) {
  19.     lgchaine = strlen(buffer);
  20.     for (i = 0; i <lgchaine; ++i) { // Pour chaque caractère de la chaine
  21.       for(j = 0; j < 6; ++j) { // Pour chaque voyelle
  22.         if(buffer[i] == voy[j] || buffer[i] == voy[j+6]) { // On teste la minuscule et la majuscule
  23.           ++compte[j];
  24.           break; // Si on a trouvé une voyelle, inutile de tester les autres
  25.         }
  26.       }
  27.     }
  28.   }
  29.   fclose(fichier);
  30.   printf("Votre texte comporte :\n" );
  31.   for(i = 0; i < 6; ++i) {
  32.     printf("%d fois la lettre %c\n", compte[i], voy[i]);
  33.   }
  34.  
  35.   return EXIT_SUCCESS;
  36. }
 

La même chose avec un switch:

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #define TAILLE_MAX 1000
  4. int main(int argc, char *argv[])
  5. {
  6.   char voy[6] = {'a', 'e', 'i', 'o', 'u', 'y'};
  7.   int compte[6] = {0};
  8.   char buffer[TAILLE_MAX];
  9.   FILE* fichier = fopen("test.txt", "r" );
  10.   int i;
  11.   if (!fichier) {
  12.     printf("Cannot open text.txt\n" );
  13.     return EXIT_FAILURE;
  14.   }
  15.   while (fgets(buffer, TAILLE_MAX, fichier)) {
  16.     i = 0;
  17.     while (buffer[i]) {
  18.       switch (buffer[i]) {
  19.       case 'a': case 'A': ++compte[0]; break;
  20.       case 'e': case 'E': ++compte[1]; break;
  21.       case 'i': case 'I': ++compte[2]; break
  22.       case 'o': case 'O': ++compte[3]; break;
  23.       case 'u': case 'U': ++compte[4]; break;
  24.       case 'y': case 'Y': ++compte[5]; break;
  25.       default: break;
  26.       }
  27.       ++i;
  28.     }
  29.   }
  30.   fclose(fichier);
  31.   printf("Votre texte comporte :\n" );
  32.   for(i = 0; i < 6; ++i) {
  33.     printf("%d fois la lettre %c\n", compte[i], voy[i]);
  34.   }
  35.  
  36.   return EXIT_SUCCESS;
  37. }


A+,

Message cité 1 fois
Message édité par gilou le 17-04-2010 à 16:06:12

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1985116
Sve@r
Posté le 17-04-2010 à 18:12:55  profilanswer
 

gilou a écrit :


Une version un peu plus évoluée, qui teste aussi les majuscules:

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define TAILLE_MAX 1000
  5. int main(int argc, char *argv[])
  6. {
  7.   char voy[12] = {'a', 'e', 'i', 'o', 'u', 'y',
  8.                   'A', 'E', 'I', 'O', 'U', 'Y'};
  9. ...
  10.            if(buffer[i] == voy[j] || buffer[i] == voy[j+6]) { // On teste la minuscule et la majuscule
  11. }




Mouais. tolower() aurait été ici assez approprié...

Code :
  1. if(tolower(buffer[i]) == voy[j]) { // On teste la minuscule et la majuscule
  2. ...


 
Là où on s'amuserait, ce serait pour tester les é, è, ê, ë, î, ï, ...


Message édité par Sve@r le 17-04-2010 à 18:14:54

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1985120
gilou
Modérateur
Modzilla
Posté le 17-04-2010 à 18:26:54  profilanswer
 

En effet. ça serait surtout approprié dans le switch (buffer[i])
un switch (tolower(buffer[i])) permet de virer la moitié des cases du switch.
De toute façon, si j'avais vraiment codé cela en dehors d'une amélioration du code donné, j'aurais introduit une structure de donnée struct avec un champ lettre et un champ compte, car c'est ce que suggère le problème.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1985127
Sve@r
Posté le 17-04-2010 à 18:45:25  profilanswer
 

gilou a écrit :

De toute façon, si j'avais vraiment codé cela en dehors d'une amélioration du code donné, j'aurais introduit une structure de donnée struct avec un champ lettre et un champ compte, car c'est ce que suggère le problème.


 
Voire même un champ "tableau de lettres" associé au champ compte ce qui permet ainsi de compter les é, è, ê comme la même lettre...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1985133
gilou
Modérateur
Modzilla
Posté le 17-04-2010 à 19:16:04  profilanswer
 

Je ferais plutôt cela au niveau d'une fonction dédiée mytolower, car ça risque de compliquer l'algorithmique d'un exo a la base simple, mais c'est une question de gout.
 
Et on peut vite arriver aux questions métaphysiques: si on compte aussi les consonnes, un ß compte t'il pour deux s? etc
A+,


Message édité par gilou le 17-04-2010 à 19:20:21

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1985137
lassault1
Posté le 17-04-2010 à 19:35:05  profilanswer
 

Merci gilou c'est ok  :D  
 
Si j'ai compris mon 1er code test que les 6 premiers caractères sur 1000 c'est ça ou pas?
 

Code :
  1. while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
  2.           {
  3.              for(i = 0; i < 6; i++)
  4.              if(chaine[i] == voy[i])
  5.              compte[i] = compte[i] + 1;
  6.           }


 
PS: Tu utilise  for (i = 0; i <strlen(chaine); i++) mais je peut mettre aussi for (i = 0; i <TAILLE_MAX; i++) ?

mood
Publicité
Posté le 17-04-2010 à 19:35:05  profilanswer
 

n°1985143
gilou
Modérateur
Modzilla
Posté le 17-04-2010 à 19:53:22  profilanswer
 

lassault1 a écrit :

Merci gilou c'est ok  :D  
 
Si j'ai compris mon 1er code test que les 6 premiers caractères sur 1000 c'est ça ou pas?

Code :
  1. while (fgets(chaine, TAILLE_MAX, fichier) != NULL)
  2.           {
  3.              for(i = 0; i < 6; i++)
  4.              if(chaine[i] == voy[i])
  5.              compte[i] = compte[i] + 1;
  6.           }



Même pas: ton code teste si le premier caractère est 'a', si le 2e est 'e', si le 3e est 'i'... et si le 6e est 'y'. :D
 

lassault1 a écrit :

PS: Tu utilise  for (i = 0; i <strlen(chaine); i++) mais je peut mettre aussi for (i = 0; i <TAILLE_MAX; i++) ?

Surtout pas: si la ligne lue par fgets et copiée dans chaine fait moins que TAILLE_MAX caractères tu vas continuer a tester pour des caractères qui trainent dans le reste du tableau chaine, mais qui n'ont pas été mis la par fgets.
C'est a ça que sert la limitation  i <strlen(chaine): a ne tester que les caractères effectivement copiés par fgets.
fgets met un '\0' a la fin de ce qu'il copie, et c'est ce que détecte strlen pour calculer la bonne longueur.
A+,


Message édité par gilou le 17-04-2010 à 19:56:12

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1985147
lassault1
Posté le 17-04-2010 à 20:15:41  profilanswer
 

Citation :

Même pas: ton code teste si le premier caractère est 'a', si le 2e est 'e', si le 3e est 'i'... et si le 6e est 'y'.  :D


 
C'est pas ce que j'ai dis  :??:  ?
 

Citation :

Surtout pas: si la ligne lue par fgets et copiée dans chaine fait moins que TAILLE_MAX caractères tu vas continuer a tester pour des caractères qui trainent dans le reste du tableau chaine, mais qui n'ont pas été mis la par fgets.
C'est a ça que sert la limitation  i <strlen(chaine): a ne tester que les caractères effectivement copiés par fgets.
fgets met un '\0' a la fin de ce qu'il copie, et c'est ce que détecte strlen pour calculer la bonne longueur.
A+,


 
Ok !  dans ce cas strlen(chaine) sert a optimisé la boucle ?

n°1985150
Un Program​meur
Posté le 17-04-2010 à 20:26:08  profilanswer
 

Non, à la rendre correcte.  Si par hasard (ou parce que la ligne précédente était plus longue) il y a une voyelle après la fin de la ligne, tu la compterais.
 
Pour optimiser, il vaut mieux ne calculer strlen qu'une fois en stockant le résultat dans une variable, ce qu'avait fait Gilou dans une de ses versions.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1985157
gilou
Modérateur
Modzilla
Posté le 17-04-2010 à 20:59:15  profilanswer
 

lassault1 a écrit :

Citation :

Même pas: ton code teste si le premier caractère est 'a', si le 2e est 'e', si le 3e est 'i'... et si le 6e est 'y'.  :D


 
C'est pas ce que j'ai dis  :??:  ?

Non, ce que tu as dit, que tu testes seulement les 6 premier caracteres, ca signifierait que ton code teste si le premier caractère est 'a',ou 'e', ou 'i'... ou 'y', puis qu'il teste si le 2e caractère est 'a',ou 'e', ou 'i'... ou 'y', ... puis qu'il teste si le 6e caractère est 'a',ou 'e', ou 'i'... ou 'y'.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1986133
lassault1
Posté le 21-04-2010 à 00:09:15  profilanswer
 

Code :
  1. # if ((fichier = fopen("test.txt", "r" )) != NULL)
  2. #     {
  3. #       while (fgets(chaine, TAILLE_MAX, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
  4. #         {
  5. #           for (i = 0; i <strlen(chaine); i++) {
  6. #             for(j = 0; j < 6; j++) {
  7. #               if(chaine[i] == voy[j])
  8. #                 compte[j] = compte[j] + 1; // On affiche la chaîne qu'on vient de lire
  9. #             }
  10. #           }
  11. #         }


 
Pourquoi pas avoir mis tout simplement for(i = 0; i < sizeof(chaine); i++) au lieu de :
 

Code :
  1. for (i = 0; i <strlen(chaine); i++)

n°1986142
gilou
Modérateur
Modzilla
Posté le 21-04-2010 à 03:04:52  profilanswer
 

Parce que sur un tableau, sizeof d'un tableau, ca renvoie le nombre total de cases, ca se fout complètement de la position du \0 dans le tableau.
Exemple:
char chaine[8] = "Toto"; ca mt les caractères T, o, t, o et \0 en position 0, 1, 2, 3 et 4 du tableau.
sizeof(chaine) vaut 8, mais strlen(chaine) vaut 4 (4 caractères avant le \0)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1986237
lassault1
Posté le 21-04-2010 à 12:47:52  profilanswer
 

Merci gilou..


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Recherche de voyelles dans un fichier

 

Sujets relatifs
Recherche d un enregistrement en utilisant Hibernate et Struts[BATCH] creation de repertoires par parcours de fichier texte
Télécharger un fichier depuis batchRécupération des données d'un fichier .hex
[PHP/MYSQL] formulaire et modification à distance de fichierRecherche un lecteur flash progressive download complet svp
Création d'un outil de visualisation et de recherche PDFCréation d'un outil de visualisation et de recherche PDF
Transformation d'un tableau (fichier xml vers html) 
Plus de sujets relatifs à : Recherche de voyelles dans un fichier


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR