Si vous voulez être sûr que la valeur attendue par l'utilisateur coïncide avec la valeur retournée en passant la chaîne à atof (str)- y compris la notation exposant - alors le code suivant fonctionne.
Vous pouvez obtenir l'entrée en utilisant fgets (str, size, stdin), et vous n'avez même pas à supprimer la nouvelle ligne de fin avant de passer la chaîne à l'analyseur.
En outre, s'il existe une erreur d'analyse, la fonction signale l'emplacement du caractère coupable à un pointeur passé en tant qu'argument supplémentaire.
Il existe une forme longue - plus facile à lire, et une forme courte - plus facile à taper.
Forme longue:
/*
Copyright (C) 2010 S. Randall Sawyer
This code is in the public domain. It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.
*/
#include <ctype.h>
#define FAILURE (0)
#define SUCCESS (!FAILURE)
enum {
END_EXPRESSION = 0x00,
ALLOW_POINT = 0x01,
ALLOW_NEGATIVE = 0x02,
REQUIRE_DIGIT = 0x04,
ALLOW_EXPONENT = 0x08,
HAVE_EXPONENT = 0x10,
EXPECT_EXPRESSION = ALLOW_POINT | ALLOW_NEGATIVE | REQUIRE_DIGIT,
EXPECT_INTEGER = ~ALLOW_POINT,
EXPECT_POS_EXPRESSION = ~ALLOW_NEGATIVE,
EXPECT_POS_INTEGER = EXPECT_INTEGER & EXPECT_POS_EXPRESSION,
EXPECT_EXPONENT = EXPECT_INTEGER^HAVE_EXPONENT,
EXPONENT_FLAGS = REQUIRE_DIGIT | ALLOW_EXPONENT | HAVE_EXPONENT
} DoubleParseFlag;
int double_parse_long (const char * str, const char ** err_ptr)
{
int ret_val, flags;
const char * ptr;
flags = EXPECT_EXPRESSION;
ptr = str;
do {
if (isdigit (*ptr)) {
ret_val = SUCCESS;
/* The '+' here is the key: It toggles 'ALLOW_EXPONENT' and
'HAVE_EXPONENT' successively */
flags = (flags + (flags & REQUIRE_DIGIT)) & EXPECT_POS_EXPRESSION;
}
else if ((*ptr & 0x5f) == 'E') {
ret_val = ((flags & (EXPONENT_FLAGS)) == ALLOW_EXPONENT);
flags = EXPECT_EXPONENT;
}
else if (*ptr == '.') {
ret_val = (flags & ALLOW_POINT);
flags = (flags & EXPECT_POS_INTEGER);
}
else if (*ptr == '-') {
ret_val = (flags & ALLOW_NEGATIVE);
flags = (flags & EXPECT_POS_EXPRESSION);
}
else if (iscntrl (*ptr)) {
ret_val = !(flags & REQUIRE_DIGIT);
flags = END_EXPRESSION;
}
else {
ret_val = FAILURE;
flags = END_EXPRESSION;
}
ptr++;
} while (ret_val && flags);
if (err_ptr != NULL)
*err_ptr = ptr - 1;
return ret_val;
}
Forme courte:
/*
Copyright (C) 2010 S. Randall Sawyer
This code is in the public domain. It is intended to be usefully illustrative.
It is not intended to be used for any particular application. If this code is
used in any application - whether open source or proprietary, then please give
credit to the author.
*/
#include <ctype.h>
int double_parse_short (const char * str, const char ** err_ptr)
{
int ret_val, flags;
const char * ptr;
flags = 0x07;
ptr = str;
do {
ret_val = (iscntrl (*ptr)) ? !(flags & 0x04) : (
(*ptr == '.') ? flags & 0x01 : (
(*ptr == '-') ? flags & 0x02 : (
((*ptr & 0x5f) == 'E') ? ((flags & 0x1c) == 0x08) : (
(isdigit (*ptr)) ? 1 : 0))));
flags = (isdigit (*ptr)) ?
(flags + (flags & 0x04)) & 0x1d : (
((*ptr & 0x5f) == 'E') ? 0x0e : (
(*ptr == '-') ? flags & 0x1d : (
(*ptr == '.') ? flags & 0x1c : 0)));
ptr++;
} while (ret_val && flags);
if (err_ptr != NULL)
*err_ptr = ptr - 1;
return ret_val;
}
J'espère que cela aide!
Ok c'est quoi scanf ("% * c"); tout sur? –
Il lit le caractère suivant - peut-être une nouvelle ligne, peut-être quelque chose d'autre - sans l'assigner à quelque chose. –
Ok, merci ..... –