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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
| #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/* -tc- Je recommande de passer un pointeur sur un tableau de caracteres
non modifiable en argument. ATTENTION: les identificateurs ayant la
forme is[a-z]* sont reserves pour l'implantation. Je modifie le nom
de ta fonction en is_number */
int is_number(char const *s)
{
/* -tc- Attention: si s est NULL, tu obtiens une erreur de
segmentation. Je recommande de tester la valeur de s */
int ret = 0;
if (s != NULL)
{
size_t len = strlen(s);
/* -tc- Si la chaine est vide chiffre, on sait que ce n'est pas
un nombre */
if (len > 0)
{
int err = 0;
/* -tc- perso, je suis contre modifier la valeur de s.
Si un jour tu veux modifier ta fonction et que, pour
une raison x ou y, tu as besoin de recuperer l'adresse
du debut de ta chaine... */
char const *pc = s;
/* Skip over white spaces. */
/* -tc- C'est une question de gouts, mais je recommande de tjs
utiliser les accolades, meme pour les blocs de 1
instruction */
/* -tc- Il est conseille de convertir les caracteres passes aux
fonctions is*() en unsigned char declarees dans ctype.h avant
la conversion implicite en int */
while (isspace((unsigned char) *pc))
{
++pc;
}
if ((*pc == '+' || *pc == '-'))
{
++pc;
}
/* -tc - Le probleme de ton implantation, c'est qu'elle accepte
comme nombre les chaines "+ ", "- ", ".". Voila l'algo que
j'implanterais */
if (isdigit((unsigned char) *pc))
{
while (isdigit((unsigned char) *pc))
{
++pc;
}
if (*pc == '.')
{
++pc;
}
while (isdigit((unsigned char) *pc))
{
++pc;
}
}
else if (*pc == '.')
{
++pc;
/* -tc- Pour avoir un nombre, '.' doit etre au moins suivit
d'un chiffre. */
if (isdigit((unsigned char) *pc))
{
while (isdigit((unsigned char) *pc))
{
++pc;
}
}
else
{
err = 1;
}
}
else
{
err = 1;
}
if (!err && (*pc == 0 || isspace((unsigned char) *pc)))
{
ret = 1;
}
}
}
return ret;
}
/* -tc- test unitaire */
struct test {
char const *data;
int result;
};
int main(void)
{
struct test tdata[] = {
{"123.1234", 1},
{" 123.1234", 1},
{"+123.1234", 1},
{" +123.1234", 1},
{" + 123.1234", 0},
{" -123.1234", 1},
{" +", 0},
{" + ", 0},
{" .", 0},
{" . ", 0},
{" +.", 0},
{" +. ", 0},
{" +.0", 1},
{" a123.1234", 0},
{" 123a.1234", 0},
{" 123.1234a", 0},
{" +123.1234a", 0},
{"+123.1234 a", 1}
};
size_t i;
int err = 0;
for (i = 0; i < sizeof tdata / sizeof *tdata; i++)
{
int rv = is_number(tdata[i].data);
printf("Test %02u: %-15s... ", (unsigned int) i, tdata[i].data);
if (rv == tdata[i].result)
{
printf("passed!\n");
}
else
{
printf("failed!\n");
err = 1;
}
}
printf("\n");
if (err == 0)
{
printf("P A S S E D!\n");
}
return EXIT_SUCCESS;
} |
Partager