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 :

Le caractere 'O'.?


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut Le caractere 'O'.?
    Bonjour à tou(te)s,
    le programme qui pose problème est destiné à lire une ligne de texte en entrée, et à remplacer tous les espaces que celle-ci peut eventuellement contenir par "_". Mon bout de code, et après je vous explique ce qui ne va pas:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
       char caractereLu = ' ';
       long phrase = 0;
       scanf("%ld", &phrase);
     
       while(caractereLu != '\n')
       {
           scanf("%c", &caractereLu);
             if(caractereLu != ' ')
                printf("%c", caractereLu);
             else
               printf("_");
       }
     
       return 0;
    }
    Lorsque la ligne de texte est "ceci est un exemple" j'obtiens bien en sortie "ceci_est_un_exemple" mais lorsque la ligne de texte est "0 1 2 3 4" j'obtiens "_1_2_3_4", pourquoi le 0 est ignoré? Il n'est pas considéré comme un espace? Ce serait pourtant le seul cas qui expliquerait cette sortie "imprévue".
    Merci à ceux qui passent par là!

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Preez
    le programme qui pose problème <...>
    Ton code présente un comportement indéfini. (pas de prototype pour les fonctions variadics. C'est obligatoire).
    Project : Forums
    Compiler : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `main':
    main.c:6: warning: implicit declaration of function `scanf'
    main.c:12: warning: implicit declaration of function `printf'
    Linking console executable: C:\dev\forums\forums.exe
    Process terminated with status 0 (0 minutes, 4 seconds)
    0 errors, 2 warnings
    Il manque <stdio.h>

    Le comportement du programme est conforme aux attentes.

    Quand on tape 0 1 2 3 4, les caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {'0', ' ', '1', ' ', '2', ' ', '3', ' ', '4', '\n'}
    sont entrés dans stdin.

    Lorsque scanf() est appelé avec %ld, il cherche à convertir ce qu'il peut jusqu'au premier séparateur (ici, ESPACE ou ' ').

    Le '0' est donc extrait et converti dans phrase (drôle de nom pour un entier...)
    Il reste donc dans stdin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {' ', '1', ' ', '2', ' ', '3', ' ', '4', '\n'}
    Ensuite, une boucle lit les caractères un par un et affiche ce qui est lu sauf ' ' qui est remplacé par '_', et le '\n', car on s'arrête dès qu'on le detecte (attention, la fin de lecture n'est pas testée).

    Il n'y a donc aucun mystère, les caractères suivants sont envoyés vers stdout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {'_', '1', '_', '2', '_', '3', '_', '4'}
    ce qui donne bien :

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Preez
    Bonjour à tou(te)s,
    le programme qui pose problème est destiné à lire une ligne de texte en entrée, et à remplacer tous les espaces que celle-ci peut eventuellement contenir par "_". Mon bout de code, et après je vous explique ce qui ne va pas:
    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
    int main()
    {
       char caractereLu = ' ';
       long phrase = 0;
      scanf("%ld", &phrase);
    
       while(caractereLu != '\n')
       {
           scanf("%c", &caractereLu);
             if(caractereLu != ' ')
                printf("%c", caractereLu);
             else
               printf("_");
       }
    
       return 0;
    }
    Est-ce que c'est bien volontaire? Je me demande si ce n'est pas lui qui consomme le zéro initial.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut
    effectivement! En supprimant le scanf j'arrive à avoir une sortie "prévue". mais c'est invraisemblable, comment peut-on saisir une ligne de texte sans le scanf()???
    Merci pour ces réponses rapides et consises.
    (Emmanuel, la stdio.h est bien incluse.)

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Preez
    effectivement! En supprimant le scanf j'arrive à avoir une sortie "prévue". mais c'est invraisemblable, comment peut-on saisir une ligne de texte sans le scanf()???
    fgets() + clean() (évoquée 2 fois sur le forum aujourd'hui).
    (Emmanuel, la stdio.h est bien incluse.)
    Ben, je ne le vois toujours pas, je laisse donc ma remarque...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut
    Bon, mon problème précédant étant résolu (merci encore à vous, même si j'ai beaucoup de mal Emmanuel à comprendre mon erreur, mais je poserai les quelques questions sur ce sujet à la fin!) j'en profite pour vous soumettre l'exercice suivant qui ne va pa non plus.
    C'est un programme tout bête qui consiste à demander un caractère à l'utilisateur, et à retourner "minuscule" si celui-ci est une minuscule, "majuscule" si celui-ci est une majuscule, et autre pour... les autres !
    Mon bout de code:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
       char caractereLu = ' ';
       scanf("%c", &caractereLu);
     
       if(caractereLu >= 'a')
          {
              if(caractereLu <= 'z')
              printf("minuscule");
          }
       else if(caractereLu >= 'A')
          {
              if(caractereLu <= 'Z')
              printf("majuscule");
          }
       else
       printf("autre");
     
       return 0;
    }
    Il semble que je ne prenne pas en compte tous les cas possibles, et je me demande lesquels j'oublie? pour toutes les char entre 'a' et 'z' c'est minuscule, pour les char entre 'A' et 'Z' c'est majuscule, et pour les autres, c'est autre...
    Où se situe mon erreur??

    -En réponse à Emmanuel:
    Qu'est-ce que "stdin"? Une libraire? une fonction de stdio.h? Je crois que je commence à comprendre mon erreur, "phrase" pour moi était destinée à recueillir la phrase rentrée par l'utilisateur, alors que tout ça est apparement inutile. Merci!

  7. #7
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    islower/isupper dans <ctype.h>

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Preez
    C'est un programme tout bête qui consiste à demander un caractère à l'utilisateur, et à retourner "minuscule" si celui-ci est une minuscule, "majuscule" si celui-ci est une majuscule, et autre pour... les autres !
    Mon bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       if(caractereLu >= 'a')
          {
              if(caractereLu <= 'z')
              printf("minuscule");
          }
    }
    Mauvaise méthode (pas portable). Tu dois utiliser isupper(), islower() (<ctypes.h>).
    Qu'est-ce que "stdin"? Une libraire? une fonction de stdio.h? Je crois que je commence à comprendre mon erreur, "phrase" pour moi était destinée à recueillir la phrase rentrée par l'utilisateur, alors que tout ça est apparement inutile.
    Je crois qu'il est urgent que tu ouvres un livre de C. Visibement il te manque les bases. On ne peut pas programmer en C si non ne sait pas clairement ce que sont les flux...

    Si tu veux saisir une phrase il faut une fonction qui saisisse une ligne de texte comme fgets().

    De toutes façons, je déconseille formellement l'usage de scanf(), surtout si on ne maitrise ni le C, ni cette fonction en particulier (elle est d'usage correct difficile). De nombreux exemples fgets() + clean() (code publié) ont été donnés aujourd'hui.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut
    Je comprends bien evidemment ton impression en face de mon "manque de bases" et tes conseils d'ouvrir un livre de C. Néamoins, ma situation actuelle ne me permet ni d'avoir accès à des livres de C, ni les moyens de m'en procurer au même titre que des cours de programmation. Perseverant dans ma volonté de mieux connaître mon ordinateur et de m'en servir à d'autres fins que les usages "familiaux" (internet, bureautique...) je m'en suis donc retourné sur les cours gratuits d'Internet (developpez.com en particulier), et les exercices qui me posent problème sont des exercices tirés de ces cours, ne necissitant (à en croire les auteurs de ceux-ci) pas d'autres connaissances que celles qu'ils enseignent.
    Alors je veux bien comprendre pour quelqu'un dont la programmation est le domaine la tension dont il fait preuve, mais je n'ai ni la pretention de connaître les fonctions que j'utilise jusque dans leurs limites, ni l'arrogance de venir vous demander bêtement les soluces toutes fraîches. Une simple mise sur la voie, si ça s'accorde à mon niveau, me satisfera entièrement.
    Pour finir, si je me suis trompé de forum et que je n'ai pas ma place ici (chose compréhensible je suis un des rares, peut-être le seul, à poser des questions aussi illogiques et de "débutant" à tous les sens du terme, alors il faut me le dire clairement, je le prendrai pas mal ni quoi, et je reviendrai quand j'aurai "les bases". Mais si il y a des personnes qui ne sont pas dérangées de m'aider de me montrer les passerelles pour acquérir ces bases et de signaler ce qui me manque pour programmer stablement et proprement, je n'en serai que plus heureux.
    --------------------------------------------------------------------------
    Emmanuel j'ai compris pour les include, je vais modifier ça dans mon message d'origine. J'ai également compris (un peu tard mais bon, mieux vaut..) qu'il est important de montrer ses include dans le code pour vérifier la bonne présence des fonctions. A l'état actuel de mes cours, je n'ai jamais entendu parler de fgets(), pareil pour islower()/isupper() (Jean-marc).
    Ce dont je me suis étonné pour la saisie de la chaine de caractere, c'est que le seul scanf() qu'il y avait était dans la boucle, je ne comprends donc pas comment j'ai pu saisir ma ligne de texte dans le programme, et c'est donc grâce à Jean-Marc que mon programme fonctionne, sans que je comprenne pourquoi, l'exercice ne m'a donc rien apporté.
    Pour finir, je vais aller chercher des infos sur "les flux" et tenter, encore, de voir pourquoi mon programme ne prends pas en compte tous les cas.

    Merci à vous de m'avoir répondu.

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Forme toi avec des cours de C

    Une simple mise sur la voie, si ça s'accorde à mon niveau, me satisfera entièrement.
    C'est exactement ce qu'on a fait en t'indiquant des pistes comme islower() ou fgets(). Par contre, ton niveau, toi seul le connais. On ne sais pas ce que tu sais ou non. On se contente de donner des réponses simples standard et immédiates pour qui connait les bases du C. On ne peut évidemment pas faire un cours de C complet à chaque réponse.

    Donc, si la réponse te parle, tu la mets en oeuvre directement, sinon, tu ouvre ton livre (ou ton site de référence) tu lis la doc et tu appliques. Si une difficulté survient, tu poses une question précise.
    A l'état actuel de mes cours, je n'ai jamais entendu parler de fgets(), pareil pour islower()/isupper() (Jean-marc).
    Ca, on ne peut pas le deviner. Alors, tu veux qu'on te mette sur la voie, mais tu ne veux pas entendre parler de fonctions nouvelles ? Ce n'est pas sérieux...
    Ce dont je me suis étonné pour la saisie de la chaine de caractere, c'est que le seul scanf() qu'il y avait était dans la boucle<...>
    Si je me souviens bien, il y avait un scanf() avec avant la boucle... Il ne faut pas coder au hasard. Si tu veux comprendre les saisies, je te conseille de lire ceci (y compris les liens internes) après t'être renseigné sur ce que sont les flux, car c'est indissociable.

    http://emmanuel-delahaye.developpez....tes.htm#saisie
    http://emmanuel-delahaye.developpez....s.htm#fichiers

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut
    Oki, j'ai compris la démarche à suivre. Merci pour les liens et les conseils, je vais voir tout ça et je reviens poser mes questions si j'ai des soucis!

    Edit: Waouh, une vraie mine d'or ct'affaire! C'est super, merci!

  12. #12
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 633
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 633
    Par défaut
    Salut,

    Si tu fais le compte: 26 lettres minuscule, 26 majuscules, l'espace et les 10 chiffres, tu n'arrives qu'à ...62 caractères.

    Meme en ANSI, on dispose de ...125 caractères possibles... tu ne gères donc que... la moitié des possiblités...

    De plus, dans la table ANSI, et sauf erreur, le chiffre 0 a la valeur de caractère 48, (les 9 suivants, les valeurs suivantes), la lettre A a la valeur 65 (les 25 autres majuscules suivent) et la lettre a a la valeur 97 (les 25 autres majuscules suivent): il y a donc 6 caractères entre le dernier chiffre et la première lettre, 6 caractères entre la dernière majuscule et la première minuscule et 47 caractères (dont 31 non affichable) avant le premier chiffre

    Si tu veux te baser sur un test "plus grand" ou "plus petit", tu dois au minimum prendre en compte les valeur des caractères... et je ne suis pas sur que toutes les tables de caractères autres qu'ANSI prennent les memes valeurs pour 0, A et a...

    Le tout, sans oublier, bien sur que certaines touches (touches de fonction et fleches entre autres) renvoyent généralement deux caractères (le premier etant caractere null)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Par défaut
    D'accord, je comprends mieux pourquoi le programme ne gérait pas tous les cas. merci!
    J'ai utilisé pour la première fois islower()/isupper() et ça raccourçit beaucoup la chose, en plus de la simplifier!
    Merci à tous!

Discussions similaires

  1. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  2. éliminer un caractere d'un string
    Par no-vice dans le forum Langage
    Réponses: 5
    Dernier message: 09/08/2002, 14h55
  3. Réponses: 3
    Dernier message: 12/06/2002, 21h15
  4. Réponses: 2
    Dernier message: 29/05/2002, 20h43
  5. Probleme sur les chaines de caractere
    Par scorpiwolf dans le forum C
    Réponses: 8
    Dernier message: 06/05/2002, 19h01

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