Re: [LA-discussions] exercice de C

[ Thread Index | Date Index | More linuxarverne.org/discussions Archives ]


On Fri, Feb 11, 2011 at 09:58:00PM +0100, Florentin Garnier wrote:
> Ah oui sscanf est capable de bouler une entrée qui correspond pas à ce qui est 
> attendu? çà m'éviterai de faire des fonctions de tests ce serai achement plus 
> cool, convi, moin bordelique.

sscanf(3) te permet de scanner un même ligne plusieurs fois, et donc de
tester si la chaîne de format match pas du tout, totalement, ou
partiellement (c'est dans ce dernier cas que c'est pénible de faire de
choses avec scanf(3)).  fgets(3) te permet de lire une ligne pour en
faire ce que tu veux après (donc l'utiliser ou la laisser tomber si elle
est moisie).

En gros, la mise en œuvre c'est:

-----------8<-----------------------------------
bool valid = false;
char buffer[BUFSIZ], unit[BUFSIZ];
int n;

while (!valid) {
  printf ("Durée: ");
  fgets (buffer, BUFSIZ, stdin);
  if (2 == sscanf (buffer, "%d %s", &n, unit)) {
    if ((0 == strcmp (unit, "s")) ||
        (0 == strcmp (unit, "mn")) ||
        (0 == strcmp (unit, "h")))
      valid = true;
  }
}
-----------8<-----------------------------------


Du coup, ça se comporte pas mal même quand tu met n'importe quoi:

----8<--------------------
romain@marvin ~ % ./a.out
Durée: hd 2
Durée: 3 dd
Durée: 4 s
romain@marvin ~ % 
----8<--------------------

Si tu veux vérifier qu'il n'y a pas d'autres trucs en plus de ce que tu
cherche, il suffit d'ajouter un %c en fin de chaîne de format et
vérifier que rien n'est lu:

if (2 == sscanf (buffer, "%d %s %c", &n, unit, &e)) { ... }

Acceptera '3s', '4 s', '  5 s ', mais pas '4 s XXX'.


Romain

-- 
Romain Tartière <romain@xxxxxxxxxxxx>        http://romain.blogreen.org/
pgp: 8234 9A78 E7C0 B807 0B59  80FF BA4D 1D95 5112 336F (ID: 0x5112336F)
(plain text =non-HTML= PGP/GPG encrypted/signed e-mail much appreciated)

Attachment: pgp39NBL1lGGO.pgp
Description: PGP signature



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/