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 :

Saisie ne prenant pas le premier élément de la boucle


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2011
    Messages : 90
    Par défaut Saisie ne prenant pas le premier élément de la boucle
    bonjour à tous, voilà j'ai réalisé un devoir, mais il y a un petit truc qui m'énerve et je comprend pas pourquoi. Regardez donc ma source, et dites moi pourquoi lorsqu'on exécute le script il affiche mot 0:
    Citation Envoyé par terminal
    Combien de chaîne souhaitez vous saisir (<100)?
    3
    Veuilez saisir les chaînes à trier : Mot 0 :Mot 1 :bob
    Mot 2 :zoe
    Mot 3 :ana
    Tableau trié lexicographiquement :

    ana
    bob
    zoe
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <stdio.h>
    #include <string.h>
    main()
    {
        char MOT[100][50];
        char AIDE[50];
        int I,n;
        int J;
        int PMOT;
        printf("Combien de chîne souhaitez vous saisir (<100)?\n");
        scanf("%d",&n);
        printf("Veuilez saisir les chaînes à trier : ");
     
        /*saisie des données*/
        for(J=0;J<=n;J++)
        {
          printf("Mot %d :",J);
          gets(MOT[J]); /*ou bien scanf("%s\n",MOT[J]*/
        }
     
        /*tri du tableau par sélection directe du */
        /*prochain mot dans la suite lexicographique*/
        for(I=0;I<=n-1;I++)
        {
          /*recherche du prochain mot à droite de A[J]*/
          PMOT=I;
          for(J=I+1;J<=n;J++)
    	if(strcmp(MOT[J],MOT[PMOT])<0)
    	  PMOT=J;
          /*Echange des mots à l'aide de strcpy*/
          strcpy(AIDE,MOT[I]);
          strcpy(MOT[I],MOT[PMOT]);
          strcpy(MOT[PMOT],AIDE);
        }
     
        /*Edition du résultat*/
        printf("Tableau trié lexicographiquement : \n");
          for(J=0;J<=n;J++)
    	puts(MOT[J]);
          printf("\n");
          return 0;
    }

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /*saisie des données*/
        for(J=0;J<=n;J++)
        {
          printf("Mot %d :",J);
          gets(MOT[J]); /*ou bien scanf("%s\n",MOT[J]*/
        }
    La boucle commence à l'indice 0, il affiche "Mot 0 :", logique...

    Si ta question est de savoir pourquoi tu ne peux pas saisir le mot 0 et qu'il affiche tout de suite "Mot 1" derrière, c'est parce que tu utilises et que le caractère de retour à la ligne généré par la touche ENTREE pour finir la saisie du nombre reste dans le buffer clavier. Il est lu directement par gets à l'itération 0 de la boucle ci-dessus.



    /!\ REMARQUE TRES IMPORTANTE : il ne faut jamais utiliser gets() /!\
    Voir ces liens :
    http://c.developpez.com/faq/index.ph..._gets_vs_fgets
    http://man.developpez.com/man3/gets.3.php#L6 (section BOGUE)

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2011
    Messages : 90
    Par défaut
    Bonjour, déjà merci @ Bktero pour les quelques astuces énoncées dans le dernier post.
    Alors j'ai tenu compte des commentaires notamment celui de utilisé scanf au lieu de gets (que je vais bannir de mon langage). Persiste un problème. le terminal attend deux lignes pour le mot 0:; J'ai aussi initialisé le début de ma boucle à 1. le prog demande toujours deux lignes pour mot 1. arf. Je pense que , c'est un problème de signe (<, <=), ou pas ?
    Merci de votre aide et bonne journée.
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #include <stdio.h>
    #include <string.h>
    main()
    {
        char MOT[100][50];
        char AIDE[50];
        int I,n;
        int J;
        int PMOT;
        printf("Combien de chaîne souhaitez vous saisir (<100)?\n");
        scanf("%d",&n);
        printf("Veuilez saisir les chaînes à trier ( < 50 carctères max. par chaîne):\n ");
     
        /*saisie des données*/
        for(J=1;J<=n;J++)
        {
          printf("Mot %d :",J);
         //gets(MOT[J]);
         scanf("%s\n",MOT[J]);
        }
     
        /*tri du tableau par sélection directe du */
        /*prochain mot dans la suite lexicographique*/
        for(I=0;I<=n-1;I++)
        {
          /*recherche du prochain mot à droite de A[J]*/
          PMOT=I;
          for(J=I+1;J<=n;J++)
     
    	if(strcmp(MOT[J],MOT[PMOT])<0)
    	  PMOT=J;
          /*Echange des mots à l'aide de strcpy*/
          strcpy(AIDE,MOT[I]);
          strcpy(MOT[I],MOT[PMOT]);
          strcpy(MOT[PMOT],AIDE);
        }
     
        /*Edition du résultat*/
        printf("Tableau trié lexicographiquement : \n");
          for(J=1;J<=n;J++)
    	puts(MOT[J]);
          printf("\n");
          return 0;
    }

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    1)
    utilisé scanf au lieu de gets
    Je n'ai jamais dit cela et les liens que je t'ai donné disent d'utiliser fgets !

    Le f de scanf veut dire "formaté", ce qui signifie que les entrées doivent avoir un format bien particulier. Je te conseille de lire cet article : http://xrenault.developpez.com/tutoriels/c/scanf/
    Il faut savoir qu'un utilisateur ne respectera pas ce formatage très souvent. La solution simple est d'utiliser fgets pour récupérer une chaine de taille maximale connue et d'en extraire les informations que l'on souhaite ou signaler une erreur si la chaine ne contient pas ce qu'on attend.

    La construction de fonctions solides pour des saisies utilisateurs n'est pas chose aisée. Je te conseille de lire cette page :
    http://emmanuel-delahaye.developpez....ees-solides-c/




    2) Tu as utilisé des accents dans ton code. Ce n'est pas une bonne idée car ils s'affichent généralement très mal.



    3) Tu utilises toujours scanf("%d",&n); pour récupérer ton nombre, mais chance pour toi, scanf("%s\n",MOT[J]); attend forcément une chaine avant le retour à la ligne et ne termine donc plus la saisie directement. Comme le l'ai dit, la chaine doit être formatée d'une certaine manière et le \n dans le format doit poser soucis puisqu'avec scanf("%s",MOT[J]);, ça marche mieux.



    4)
    J'ai aussi initialisé le début de ma boucle à 1.
    sauf que les indices dans ton tableau commence toujours à zéro, donc la première ligne de ton tableau de chaines de caractères reste vide.


    5) La fonction main n'a pas le bon prototype, il faut au moins mettre int main(void). D'ailleurs, ton compilateur a dû émettre un warning à ce sujet.



    PS : essaye le code suivant pour voir les problèmes avec scanf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char chaine[100];
        printf("Ecrire : ");
        scanf("%s\n", chaine);
        printf("\n\nLu '%s'\n\n", chaine);
     
        printf("Ecrire encore : ");
        scanf("%s\n", chaine);
        printf("\n\nPuis lu '%s'", chaine);
        return 0;
    }
    Saisi : "bonjour developpez", ENTREE, ".com", ENTREE. Regarde.

    Recommence mais en enlevant les \n dans les scanf.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Novembre 2011
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2011
    Messages : 90
    Par défaut
    A oui en effet, un \n en trop. Merci encore, avant de m'en rendre compte de cette stupide faute, j'ai bien pris note des liens proposés. du coup j'ai essayer de remplacer (sans succès)la fonction scanf par fgetc.
    Quand j'ai dis que je vais bannir de mon langage la fonction gets, c'est parce que :
    Citation Envoyé par Bktero
    /!\ REMARQUE TRES IMPORTANTE : il ne faut jamais utiliser gets() /!\
    J'aime pas la programmation divinatoire. j'ai réussis à écrire ce programme en ouvrant un livre d'exercice où un exercice similaire était proposé. D'un côté je ne sais même pas sûr que c'est ça qu'ils veulent pour mon devoir.
    Il nous demande de partir d'un programme qui trie des entiers et de le transformer pour qu'il trie des chars. J'ai ré-écrit le programme duquel nous devons partir, et il ne fonctionne pas. Que faire ? leur dire f**k et je rend un programme qui marche,(taper 1) ou bien corriger leur programme et faire se que l'on demande (taper 2)?

  6. #6
    Membre émérite
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Par défaut
    toujours prendre les bonnes habitudes le plus tôt possible, tout simplement

  7. #7
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Citation Envoyé par sk8trasher Voir le message
    A oui en effet, un \n en trop. Merci encore, avant de m'en rendre compte de cette stupide faute, j'ai bien pris note des liens proposés. du coup j'ai essayer de remplacer (sans succès)la fonction scanf par fgetc.
    Quand j'ai dis que je vais bannir de mon langage la fonction gets, c'est parce que :

    J'aime pas la programmation divinatoire. j'ai réussis à écrire ce programme en ouvrant un livre d'exercice où un exercice similaire était proposé. D'un côté je ne sais même pas sûr que c'est ça qu'ils veulent pour mon devoir.
    Il nous demande de partir d'un programme qui trie des entiers et de le transformer pour qu'il trie des chars. J'ai ré-écrit le programme duquel nous devons partir, et il ne fonctionne pas. Que faire ? leur dire f**k et je rend un programme qui marche,(taper 1) ou bien corriger leur programme et faire se que l'on demande (taper 2)?

    N'oublie pas qu'un jour tu travailleras surement en entreprise, et si le cas échéant un jour tu décides de "taper 1", tu te taperas la porte direct. Il faut toujours (question bête) faire ce qu'on te demande, mais tu as le droit d'en faire plus, A PARTIR DU MOMENT OU TU AS FAIS CE QU'ON TE DEMANDE (très important).

    Une fois, j'ai fais un devoir (TP noté) en ADA ou j'avais un peu d'avance, alors j'ai paufiné mon programme pour qu'il donne le choix en console au prof de choisir quel exercice éxécuter, avec également la possibilité d'afficher le code du programme en question (tout ça pour l'aider à corriger mon devoir plus rapidement). Il m'a mis 19/20 pour "ne pas avoir respecté les consignes". Au final j'ai eu 20 car un autre prof avait trouvé ça dégueulasse, mais c'est pour te dire, que même quand tu fais ce qu'on te demande ET plus, tu n'est pas sur d'en recevoir les honneurs, alors faire autre chose que ce qu'on te demande, je n'y crois pas trop...

    bon courage pour la suite

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

Discussions similaires

  1. [XPATH 1.0] Traitement différent pour premier élément d'une boucle
    Par toopac dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 20/07/2011, 09h28
  2. Réponses: 1
    Dernier message: 06/05/2009, 00h40
  3. Réponses: 12
    Dernier message: 29/04/2005, 14h37
  4. Réponses: 2
    Dernier message: 11/01/2005, 14h10
  5. Saisie clavier marche pas
    Par Dokho1000 dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 11/03/2004, 12h16

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