Pb pour rentrer une chaine de caractere dans un tableau !

Pb pour rentrer une chaine de caractere dans un tableau ! - C - Programmation

Marsh Posté le 10-04-2010 à 14:42:51    

Bonjour à tous !
 
Nous avons un projet en algorithmique et programmation à réaliser pour notre école ! Nous devons créer un programme qui détermine le nb de couple d'anagramme par phrase! Pour cela on doit demander a l'utilisateur de rentrer le nb de caractères de sa chaine, dc jusque là pas de pb et ensuite créer un tableau en fonction du nb indiqué, afin dit mettre la phrase qu'on lui demandera par la suite!  
 
Notre pb est le suivant : lorsque l'on rentre la phrase dans le tableau et que l'on affiche ensuite ce tableau seul le premier mot apparait et le reste disparait ! On ne sait pas du tout d'ou vient le pb car nous sommes vraiment très debutantes en programmation !
 
Voici la copie de l'ebauche de notre algo :
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
 
int main()
{
    int n;
    char phrase [200];
    printf ("Entrez le nombre de caracteres de votre phrase : " );
    scanf ("%d",&n);
    if ((n==0) || (n>200)) {
        printf ("Entrez un autre nombre de caractere pour votre phrase" );
    }
    printf ("Entrez votre phrase : " );
    scanf ("%s", phrase);
    printf (phrase);
 
}
 
 
Par exemple si l'on rentre "la maison" seul le "la" apparait !
 
Si vous avez des suggestions  ;) !
Merci d'avance !
 

Reply

Marsh Posté le 10-04-2010 à 14:42:51   

Reply

Marsh Posté le 10-04-2010 à 15:05:12    

Lis la documentation de scanf(), en tapant "man scanf" en ligne de commande si tu es sur un unix quelconque, ou sinon dans google, ça fonctionne aussi.
Je copie-colle la partie qui nous intéresse :

Citation :

Conversions
Les caractères modificateurs de type suivant peuvent se apparaître dans une spécification de conversion :
[...]
s
    Correspond à une séquence de caractères différents des caractères blancs. Le pointeur correspondant doit être un pointeur sur un tableau de caractères qui doit être assez large pour accueillir toute la séquence d'entrée, ainsi que l'octet nul final (« \0 ») qui est ajouté automatiquement. La conversion s'arrête au premier caractère blanc, ou à la longueur maximale du champ.

 

Il faut voir scanf() comme une fonction de lecture de données formatées. Cette fonction est donc d'une part mal adaptée à la lecture de données brutes, et d'autre part très difficile à appréhender et à utiliser correctement pour les débutants (elle est bien plus complexe qu'il n'y paraît). Je rêve toujours de pouvoir brûler les professeurs qui commencent par cette fonction pour enseigner le C.

 

Essaie plutôt avec la fonction fgets(), bien plus simple à utiliser et adaptée à votre besoin :
http://www.linux-kheops.com/doc/ma [...] 3.txt.html


Message édité par Elmoricq le 10-04-2010 à 15:05:57
Reply

Marsh Posté le 10-04-2010 à 21:53:11    


Déja merci bcp pour les réponses, malheuresement nous somme vraiment très très debutantes et nous avons bcp de mal a comprendre tout le langage  :pt1cable: !
 
Nous avons qd même essayé de modifier notre algo, voici ce que ca donne :
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
 
int main()
{
    int n;
    char phrase [200];
    printf ("Entrez le nombre de caracteres de votre phrase : " );
    scanf ("%d",&n);
    if ((n==0) || (n>200)) {
        printf ("Entrez un autre nombre de caractere pour votre phrase" );
    }
    printf ("Entrez votre phrase : " );
    scanf ("%s", phrase);
    fgets (phrase, 200, stdin);
    printf ("vous avez tape : %s", phrase);
 
    return 0;
}
 
Nous avons quelques questions :
 
- Est ce que la fonction fgets doit remplacer la fonction scanf ? car si on enlève scanf et que l'on compile, nous n'arrivons plus à rentrer de phrase !
 
- A l'inverse si on laisse les deux fonctions, on peut rentrer une phrase mais le premier mot n'apparait pas !
 
 
Merci bcp !

Reply

Marsh Posté le 10-04-2010 à 23:23:27    

Salut
 
C'est encore dû à scanf. Lors de la lecture du nombre de caractères. Il me semble qu'il ne prend pas le retour chariot du coup c'est fgets qui le lit et donc qui s'arrête là.
 
Il y a une astuce, un truc genre %*c mais le mieux c'est d'utiliser fgets() pour demander le nombre à l'utilisateur puis de convertir la chaîne de caractères obtenue en nombre avec strtol().


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 11-04-2010 à 00:46:23    

ton printf(phrase) c'est une TRES mauvaise idée. ne JAMAIS mettre en 1er parametre de printf un imput utilisateur, tu t'exposes a des mecs qui vont faire faire des printf("%n%n%n%n%n" ); a ton soft, ce qui va le faire planter dans la douleur et le sang. prefere un printf("%s\n", truc); ou encore mieux un puts(truc);

Reply

Marsh Posté le 11-04-2010 à 11:28:24    

Quand tu fais:

Code :
  1. printf ("Entrez le nombre de caracteres de votre phrase : " );
  2.   scanf ("%d",&n);


Il reste un "\n" dans le buffer. Quand tu fais ensuite fgets, il voit ce "\n" et considère que c'est la chaine a lire, et retourne avec elle.
ca se voit très bien si tu remplace ton code par:

Code :
  1. printf ("Entrez le nombre de caracteres de votre phrase : " );
  2.     if( fgets( phrase, 200, stdin) == NULL)
  3.          printf( "fgets error\n" );
  4.       else
  5.          printf( "-->%s<--\n", phrase);
 

Il va donc falloir nettoyer stdin avant d'appeller fgets. Il semblerait logique de faire un fflush(stdin) avant le fgets, et ça marche très bien sous windows. MAIS, pour des raisons historiques, il ne faut pas faire fflush(stdin), car ça a un comportement indéfini [bon, ici ça marche, mais ça pourrait ne pas être le cas sous un autre environnement].
Donc il va falloir écrire une petite fonction de nettoyage:

 
Code :
  1. #define JUNK_BUFFER_SIZE 255
  2. void cleanup_stdin() {
  3.   static char junk_buffer[JUNK_BUFFER_SIZE];
  4.   char *s;
  5.   int i = 0;
  6.   while (s = fgets(junk_buffer, JUNK_BUFFER_SIZE, stdin)) {
  7.     i = strlen(s);
  8.     if ( (!i) || junk_buffer[i-1] == '\n')
  9.       break;
  10.   }
  11. }


et dans ton code, tu l'appèles après avoir lu stdin avec scanf:

Code :
  1. printf ("Entrez le nombre de caracteres de votre phrase : " );
  2.   scanf ("%d",&n);
  3.   cleanup_stdin();


et tout rentrera dans l'ordre.

 

La fonction de nettoyage de stdin lit tout ce qu'il reste dans stdin par tranches de 255 caractères ici, jusqu'a ce qu'il n'y ait plus rien ou bien que l'on ait (enfin) rencontré un '\n' (qui est alors a la fin de ce qu'on a lu par définition de fgets, d'ou le test junk_buffer[i-1] == '\n').

 

En résumé:

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define JUNK_BUFFER_SIZE 255
  4. void cleanup_stdin() {
  5.   static char junk_buffer[JUNK_BUFFER_SIZE];
  6.   char *s;
  7.   int i = 0;
  8.   while (s = fgets(junk_buffer, JUNK_BUFFER_SIZE, stdin)) {
  9.     i = strlen(s);
  10.     if ((!i) ||  junk_buffer[i-1] == '\n')
  11.       break;
  12.   }
  13. }
  14. int main()
  15. {
  16.   int n;
  17.   char phrase [200];
  18.    
  19.   printf ("Entrez le nombre de caracteres de votre phrase : " );
  20.   scanf ("%d",&n);
  21.   cleanup_stdin();
  22.   if ((n==0) || (n>200)) {
  23.     printf ("Entrez un autre nombre de caractere pour votre phrase" );
  24.   }
  25.   printf ("Entrez votre phrase : " );
  26.   fgets (phrase, 200, stdin);
  27.   printf ("vous avez tape : %s", phrase);
  28.   return 0;
  29. }
 


A+,


Message édité par gilou le 11-04-2010 à 12:59:20

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed