Bien programmer en langage C
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment :
Coffret dresseur d’élite ETB ...
Voir le deal
56.90 €

[ANSI non-ANSI]caractère affichable, non affichable

Aller en bas

[ANSI non-ANSI]caractère affichable, non affichable Empty [ANSI non-ANSI]caractère affichable, non affichable

Message  -ed- Lun 26 Mai 2008 - 22:31

Bonjour,

Voilà je tente de réaliser un petit programme qui me permettrai d' afficher des caractères si ils sont affichable ( i.e 'ANSI') sinon un
' . ' (point) .

Pour le faire j'utilise la fonction ' isprint ', dans le but de faire le distinction; et j' ai réaliser un tableau de 'char' avec les lettres classiques pour mon premier test.
Je teste ... bien entendu pas de problèmes.

Mais je me demande comment faire pour pour réaliser mon teste dans le cas contraire, ou les éléments du tableau sont non affichable (i.e non-ANSI) .
Que dois je mettre dans mon tableau pour qu' il m' affiche des ' . ' (point)?

Bon je ne sais pas, si j' ai été assez claire ?!

Voici mon code :

Quelques remarques :

- Je recommande de placer les fonctions privées (static) avant les points d'entrées (qui sont bien sûr publics). Ca évite des prototypes séparés inutiles.
Code:

static void print_char (const void *octet)
{
  /* transtypage implicite */
  BYTE *character = octet;


Certes, la conversion void* vers BYTE * est implicite, mais il faut respecter la 'constantness' :

Code:

BYTE const *character = octet;

str_aff[char_i++] = char_aff;

Je déconseille d'utiliser un opérateur unaire comme '++' dans une expression. Le comportement est indéfini (du moins, il dépend de l'implémentation et n'est donc pas portabe).

Code:

str_aff[char_i] = char_aff;
char_i++,


est probablement ce que tu voulais dire. Le mieux est d'être explicite. Le compilateur fera les optimisations qu'il jugera utiles.

- Dans les fonctions print_char() et print_hexa(), je ne vois pas bien l'utilité de passer par un pointeur. Un int suffit.(copier une adresse ou in int ne change pas grand chose au niveau performance par contre, l'indirection ralenti le processus...)

Je ne vois pas ce que vient faire ce EOF dans print_char(), et dans print_hexa(), un formatage sur 2 caractères avec 0 en tête est souhaitable.

Code:
exit (0);

n'a aucun sens à la fin du main(). return 0; suffit amplement.

Voici le code corrigé :

Code:

/*
 * include ==========================================================
 */
# include <stdio.h>
# include <ctype.h>
# include <string.h>
# include <stdlib.h>

/*
 * type =============================================================
 */

/* la plus petite unité de stockage et adressable en C */
typedef unsigned char BYTE;

/*
 * private fonctions ================================================
 */

/*
 * -------------------------------------------------------------------
 * FUNCTION : print_char()
 * -------------------------------------------------------------------
 * affiche le caractère , sinon un point
 * --------------------------------------------------------------------
 * I : octet : caractère : BYTE
 * --------------------------------------------------------------------
 * O :
 * --------------------------------------------------------------------
 */
static void print_char (int octet)
{
/* transtypage explicte de character */
  if (isprint (octet))
  {
      printf ("%c", octet);
  }
  else
      printf (".");

}

/*
 * -------------------------------------------------------------------
 * FUNCTION : print_hexa()
 * -------------------------------------------------------------------
 * affiche le caractère en hexadecimal
 * --------------------------------------------------------------------
 * I : octet : caractère : BYTE
 * --------------------------------------------------------------------
 * O :
 * --------------------------------------------------------------------
 */
static void print_hexa (int octet)
{
/* transtypage implicite */
  printf ("%02X ", (unsigned) octet);

}

/*
 * -------------------------------------------------------------------
 * FUNCTION : go_over()
 * -------------------------------------------------------------------
 * parcourt un tableau peut importe son type
 * -------------------------------------------------------------------
 * ALGO :
 * -------------------------------------------------------------------
 * I : p_tab : pointeur sur le tableau de tout type
 * I : nbr_elt : taille tableau = nombre elements
 * I : size_elt : taille des elements tableau
 * I : p_fct : pointeur sur fontion uliser avec parcour
 * -------------------------------------------------------------------
 * O :
 * -------------------------------------------------------------------
 */
static void go_over (void *p_tab, size_t nbr_elt, size_t size_elt,
                    void (*p_fct) (int))
{
  size_t elt_i;
  BYTE *data = p_tab;

  for (elt_i = 0; elt_i < nbr_elt; elt_i++)
  {
      BYTE const *p = data + elt_i * size_elt;
      p_fct (*p);
  }
}

/*
 * entry point ======================================================
 */
int main (void)
{

  size_t nelt_line = 10;      /* nombres de char ou hex par ligne */
  char str_test[] = "Le plus simple est \n"
                    "\tde mélanger les caractères\n";
  char str_aff[nelt_line];
  char char_aff;
  size_t i;
  size_t size_char;
  size_t char_i = 0;
  size_t char_j = 0;

/*
 * on utilise la boucle while car la condition d' arrêt
 * n est pas sur un compteur char_i ou char_j mais un etat de
 * teste(0 ou 1)
 */
  do
  {
      char_aff = str_test[char_j + char_i];
      str_aff[char_i] = char_aff;
      char_i++;

      if (char_i > nelt_line)
      {

/* '*str_aff' fait cf. au premier element du tableau */
        size_char = sizeof (*str_aff);

        go_over (str_aff, nelt_line, size_char, print_char);
        printf (" ");
        go_over (str_aff, nelt_line, size_char, print_hexa);
        printf ("\n");

/* reinitialiser indice du tableau */
        char_i = 0;
/* pour parcourir tableau de 10 en 10 */
        char_j = char_j + 10;

      }

  }
  while (char_aff != '\0');

/* pour afficher les char de derniere ligne */
  if (char_i > 0)
  {

      size_char = sizeof (*str_aff);

/* le (-1) pour ne pas afficher le char '\0' */
      go_over (str_aff, char_i - 1, size_char, print_char);

/* combler le vide avec des espaces */
      for (i = char_i; i <= nelt_line; i++, printf (" "));
      printf (" ");

      go_over (str_aff, char_i - 1, size_char, print_hexa);
      printf (" \n");
  }

  return 0;
}

Il produit, par exemple :
Code:

Le plus si 4C 65 20 70 6C 75 73 20 73 69
mple est . 6D 70 6C 65 20 65 73 74 20 0A
.de m.lang 09 64 65 20 6D E9 6C 61 6E 67
er les car 65 72 20 6C 65 73 20 63 61 72
act.res. 61 63 74 E8 72 65 73 0A

Press ENTER to continue.


-ed- a écrit:
- Dans les fonctions print_char() et print_hexa(), je ne vois pas bien l'utilité de passer par un pointeur. Un int suffit.(copier une adresse ou in int ne change pas grand chose au niveau performance par contre, l'indirection ralenti le processus...)

Dans les fonctions en questions ' print_char() et print_hexa()' j'utilise les pointeurs, car j' essaiyais de m' amuser réaliser des fonction génériques sur la base de la fonction 'go_over', qui n' est autre que le modèle de la fonction 'parcours()' prise là:http://rperrot.developpez.com/ articles/c/genericite/ .
Je me suis trompé sur la méthode?!
-ed-
-ed-
Admin
Admin

Messages : 290
Date d'inscription : 26/05/2008
Age : 67
Localisation : Paris 14eme arrondissement (75, France)

http://bien-programmer.fr

Revenir en haut Aller en bas

Revenir en haut


 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
Ne ratez plus aucun deal !
Abonnez-vous pour recevoir par notification une sélection des meilleurs deals chaque jour.
IgnorerAutoriser