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 :

getchar() et accents


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut getchar() et accents
    Bonjour, j'ai récemment commencé la lecture de K&R2 pour approfondir ma connaissance du C. Un des exercices a pour objectif la création d'un histogramme correspondant à longueur des mots entrés. Or, j'ai complété l'exercice et mon programme va très bien... excepté un petit détail... il compte les caractères accentués en double. Or, ma question est bien simple : pourquoi ou plutôt quelle propriété fait qu'un caractère accentué est compté comme deux ?

    Voilà mon code (le nom des variables en Anglais, car je code en Anglais, j'ai traduit pour vous les commentaires en Français) :
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <stdio.h>
    #define MAX_WORD_LENGHT  20
     
    int main(void)
    {
      int iChar, iWordLenght, i, j, iMaxValue, bDone;
      int iWords[(MAX_WORD_LENGHT+1)] = {0}; /* iWords[0] est utilisé pour les mots > 20 */
      int iColumn[(MAX_WORD_LENGHT+1)] = {0};
     
     
      /* Cette partie est utilisée pour l'entrée de données */
      iWordLenght = 0;
      bDone = 0;
     
      while(!bDone) {
     
        iChar = getchar();
     
        if(iChar == ' ' || iChar == '\t' || iChar == '\n' || iChar == EOF) {
     
          if(iWordLenght > 0 && iWordLenght <= MAX_WORD_LENGHT)
    	iWords[iWordLenght]++;
          if(iWordLenght > 0 && iWordLenght > MAX_WORD_LENGHT)
    	iWords[0]++;
          if(iChar == EOF)
    	bDone = 1;
     
          iWordLenght = 0;
        }
        else
          iWordLenght++;
      }
     
     
      /* Cette partie est utilisée pour l'affichage graphique de l'histogramme */
     
      iMaxValue = 0;
      for(i = 0; i <= MAX_WORD_LENGHT; i++)
        if(iWords[i] > iMaxValue)
    	iMaxValue = iWords[i];
     
      printf("\n");
      for(i = iMaxValue; i > 0; i--) {
        printf("%2d |", i);
        for(j = 0; j <= MAX_WORD_LENGHT; j++)
          if(iWords[j] >= i)
    	iColumn[j] = '*';
          else
    	iColumn[j] = ' ';
        for(j = 1; j <= MAX_WORD_LENGHT; j++)
          {
    	printf("%2c ", iColumn[j]);
          }
        printf("%2c|\n", iColumn[0]);
      }
      printf("   +--------------------------------------------------------------+\n");
      printf("   |01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 ++|\n");
     
      return 0;
    }
    Merci d'avance pour vos réponses!

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Salut

    Il est fortement probable que ton environnement de travail soit en utf8. Or l'utf8 (format de codage destiné à remplacer l'ASCII et normalisé depuis 2005) code les caractères particuliers sur plus d'un octet (2; 3 ou 4 parfois).

    Ce format plus étendu que l'ascii est destiné à pouvoir tout gérer (caractères cyrilliques, suédois, kanjis, etc). Mais on perd l'équivalence "1 caractère=1 octet".

    Si t'es sous Linux, tape la commande "locale". Si les variables qui s'affichent ont la valeur "utf8", c'est ça...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut
    Bingo! En effet, environnement de travail est en utf-8. Donc ce serait parce que le buffer de ma console retourne 2 octets à getchar() lorsqu'un caractère accentué est entré. Or, y-a-t'il un moyen de gérer ce petit problème ?

    Car en suivant la logique, un simple "if(iChar == 'é')" ne fonctionnerait pas, n'est-ce pas ?

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Si tu veux manipuler des chaines en UTF-8 (ou d'une manière générale avec des charactères multi-byte), il faut que tu utilises les wchar_t à la place des char, et les fonctions associées (fgetws, wcslen...).

    Attention, il faut aussi que tu initialises la locale pour que la libc sache sous quelle forme sont codées tes chaines. Tu dois donc ajouter ceci au début de ton programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (!setlocale(LC_CTYPE, "")) {
            /* Error */
    }

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Par défaut
    Je vais expérimenter avec les widechars, merci beaucoup pour vos conseils à tous les deux!

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

Discussions similaires

  1. getchar()
    Par bashou dans le forum C
    Réponses: 11
    Dernier message: 16/09/2005, 18h49
  2. Accents
    Par Sylvain Leray dans le forum XMLRAD
    Réponses: 2
    Dernier message: 26/02/2003, 16h17
  3. identification lettre (pb accent)
    Par scorbo dans le forum C
    Réponses: 5
    Dernier message: 14/12/2002, 02h59
  4. que deviennent mes accents ?!
    Par petitdns dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 28/11/2002, 09h32
  5. [Accents - XML] Problème de codage non supporté !!
    Par Smortex dans le forum Composants VCL
    Réponses: 6
    Dernier message: 24/11/2002, 11h00

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