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 :

Question sur getchar()


Sujet :

C

  1. #1
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut Question sur getchar()
    Bonjour,

    Voici un programme qui réalise la conversion d'une string minuscule en majuscule :

    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
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdbool.h>
     
    int 
    main(void)
    {
        while (true)
        {
    	signed char c = getchar();
            if (c == '\n')
                break;
     
            switch (c)
            {
              case 'é' :
                putchar('É');
                break;
     
              case 'è' :
                putchar('È');
                break;
     
              case 'ê' :
                putchar('Ê');
                break;
     
              default:
                putchar(toupper(c));
                break;
            }
        }
        putchar('\n');
     
        return EXIT_SUCCESS;
    }
    Lorsque je saisi un caractere sur stdin, il le compare à '\n' pour stopper la boucle s'il vaut stdin et réalise la conversion en majuscule sinon.

    Je ne comprend pas pourquoi les caractères en majuscule resultant de la conversion sont affiché apres mon CR (Carrier Return). Voici un exemple d'utilisation:

    kal@kal-laptop ~ $ ./caracteres
    caractères accentués
    CARACTÈRES ACCENTUÉS
    Bien que cela ne me dérange pas, je ne comprend pas pourquoi c'est ainsi et pas comme ça :

    cCaArRaAcCtTèÈrReEsS aAcCcCeEnNtTuUéÉsS
    Merci d'avance

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    C'est ce qu'on appelle la tamporisation...

    Ton programme reçoit l'information du clavier lorsque l'utilisateur a appuyé sur entrée ou que le tampon est plein.

    Jc

  3. #3
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Remarque que getchar() renvoie un int que tu castes violemment en signed char. Ensuite, tu compares ce signed char avec des valeurs int. Declare c comme etant un int, cela permet notamment de recevoir le EOF renvoye par getchar() en cas d'erreur.

  4. #4
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour,

    en C, les entrées sorties sont bufferisées.
    C'est justement ton retour charriot qui te permet de lancer le programme.
    Sinon tu peux mettre ton texte dans un fichier.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  5. #5
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Merci beaucoup, j'ai compris

    @DaZumba:
    Oui j'avais pas pensé pour le int, je souhaitais juste économiser de la place. Par contre je ne savais pas que l'évaluation d'un caractère tel que 'è' retourné un int. Merci pour l'info


  6. #6
    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 fearyourself
    C'est ce qu'on appelle la tamporisation...
    Euh, la quoi ? En franglais, la bufferisation (buffering), peut être ? ou la tamponisation en français...

  7. #7
    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 _kal_
    Je ne comprend pas pourquoi les caractères en majuscule resultant de la conversion sont affiché apres mon CR (Carrier Return).
    http://emmanuel-delahaye.developpez.com/notes.htm#fgetc

  8. #8
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut

    Comme d'habitude, je ne peux que saluer le travail que tu fournis. Explication très claire

  9. #9
    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 _kal_
    Comme d'habitude, je ne peux que saluer le travail que tu fournis. Explication très clair
    Merci. Je t'autorise de mettre un 'e' à clair...

  10. #10
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Merci. Je t'autorise de mettre un 'e' à clair...


    Le pire, c'est que j'avais mis un 'e' à l'origine. Puis j'ai pensé que ceci designait le prénom "Claire", donc il n'y avait pas de 'e'. Mais en fait non

  11. #11
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    default:
    putchar(toupper(c));
    break;
    Le "break" pour le "default case" est facultatif.

  12. #12
    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 seriousme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    default:
    putchar(toupper(c));
    break;
    Le "break" pour le "default case" est facultatif.
    Rien à voir avec default. Le dernier break est facultatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            switch (c)
            {
              case 'é' :
                putchar('É');
                break;
     
              default:
                putchar(toupper(c));
            }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            switch (c)
            {
              default:
                putchar(toupper(c));
                break;
     
              case 'é' :
                putchar('É');
            }
    etc.

  13. #13
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Rien à voir avec default. Le dernier break est facultatif :
    Exact mais souvent il y a un "default case" même si il est vide.

  14. #14
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    En effet, je n'ai fait que recopier l'exemple du livre que je lit actuellement (Méthodologie de programmation en C99 - API POSIX).

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Quelques remarques:
    - on ne passe pas un char, surtout signed, à toupper sans le transformer en unsigned char
    - si le résultat de getchar est un int, ce n'est pas pour rien; c'est pour pouvoir traiter la fin des fichiers
    - si on veut que toupper fonctionne avec les caractères hors du jeu de base, il faut utiliser les locales

  16. #16
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    - on ne passe pas un char, surtout signed, à toupper sans le transformer en unsigned char
    Méthodologie de la programmation en C - Norme C99 - API POSIX (Page 121) :
    Si l'on change en <unsigned char c = getchar(); > la déclaration de la variable c, on obtient le résultat suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ caracteres
    caractères accentués
    CARACTèRES ACCENTUéS
    La raison de ce dysfonctionnement apparent est simple. Prenons le cas du caractère 'é', codé dans la norme ISO par la suite de bits 11101001. Sur un octet, cette valeur code la valeur décimale 233 dans le cas d'une arithmétique sans signe, et -23 dans le cas d'une arithmétique signée. Une constante caractère étant de type int, elle est signée. La valeur de la constante 'é' est -23. Par contre la variable c étant de type unsigned char, sa valeur est 233.
    La première version du programme n'est par conséquent pas portable car elle dépend de l'implémentation du type char. Pour y remédier, il faut déclarer la variable c de type signed char. Nous verrons d'autre part, dans le chapitre 6, qu'il existe un mécanisme portable appelé contrôle local, permettant de prendre en compte les spécificités des différentes langues.
    C'est pourquoi la variable c est déclaré en signed char. Par ailleurs, je ne comprend pas pourquoi il ne faut pas passer de char, surtout signed, à la fonction toupper. En effet, il y aura une promotion intégral lors de l'appel toupper(c) qui réalisera une conversion implicite de signed char vers int. Est ce due au fait qu'il y a une extension du bit de signe? Pourtant ce programme semble marcher...

    Citation Envoyé par Jean-Marc.Bourguet
    - si le résultat de getchar est un int, ce n'est pas pour rien; c'est pour pouvoir traiter la fin des fichiers
    Exact, mais l'auteur ne le précise pas dans l'ouvrage (du moins pas encore). Mais c'est vrai qu'il faut un int pour traiter EOF.

    Citation Envoyé par Jean-Marc.Bourguet
    - si on veut que toupper fonctionne avec les caractères hors du jeu de base, il faut utiliser les locales
    Là par contre, mon niveau de connaissance n'atteint pas encore ce stade. Bientôt si tout va bien

    Merci en tout cas pour ces remarques constructives.

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Au fait : Pour ceux qui veulent jouer avec l'unicode, et les wchar_t, Je ne crois pas qu'il y ait problème de ce coté : wchar_t est supposé non-signé. À moins qu'il ne faille utiliser wint_t ?
    Edit: wchar_t n'est donc pas forcément non-signé, mais on peut passer directement un wchar_t aux fonctions de <wctype.h>.

    Et pour ceux qui tournent sous Windows et souhaitent compiler dans les deux modes (ils utilisent donc les TCHAR), ils ne peuvent convertir directement en unsigned char ou en int. Heureusement, le type _TUCHAR (déclaré dans tchar.h) est fait pour cela.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    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 _kal_
    Méthodologie de la programmation en C - Norme C99 - API POSIX (Page 121) :
    J'ai pas lu ce bouquin, mais les explications que tu cites sont vaseuses...

    C'est pourquoi la variable c est déclaré en signed char. Par ailleurs, je ne comprend pas pourquoi il ne faut pas passer de char, surtout signed, à la fonction toupper.
    Parce que la norme demande que les int passes aux fonctions de ctype.h soient soit EOF, soit des unsigned char converti en int.

    Si tu utilises un int, il y a deux problemes: tout d'abord tu ne peux pas faire la distinction entre 'ÿ' et EOF si tes char sont signes, ensuite tu risques de passer d'autres valeurs negatives auxquelles toupper ne s'attend pas. Une implementation classique etant d'indexer un tableau, tu peux lire n'importe quoi ou meme arreter brutalement ton programme.

  19. #19
    Membre confirmé Avatar de _kal_
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2006
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2006
    Messages : 178
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Si tu utilises un int, il y a deux problemes: tout d'abord tu ne peux pas faire la distinction entre 'ÿ' et EOF si tes char sont signes, ensuite tu risques de passer d'autres valeurs negatives auxquelles toupper ne s'attend pas. Une implementation classique etant d'indexer un tableau, tu peux lire n'importe quoi ou meme arreter brutalement ton programme.
    Ok, merci j'ai compris

  20. #20
    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 Médinoc
    wchar_t est supposé non-signé
    Pas a ma connaissance.

    À moins qu'il ne faille utiliser wint_t ?
    Pas non plus garanti non signe a ma connaissance.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [debutant] Questions sur 1 futur projet
    Par cyrull22 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 28/04/2003, 21h49
  2. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23
  3. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  4. Réponses: 2
    Dernier message: 11/08/2002, 21h27
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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