#include #include #include /* * readString * * Lit (nbCar-1) caractères sur stdin et les stocke à l'adresse chaine * Le buffer de stdin est vide après l'appel de la fonction * * * Retour : * - si la lecture s'est passée correctement : 0 * - si la chaîne a été tronquée : 1 * - si erreur de lecture, si nbCar <= 1 ou si chaine == NULL : 2 */ unsigned int readString (char chaine[], size_t nbCar) { unsigned int err; /* si la saisie est impossible */ if (nbCar <= 1 || chaine == NULL) { err = 2; } /* si elle est possible */ else { int carTemp; unsigned int i = 0; /* lecture de stdin et copie dans la chaîne */ while ( (carTemp = fgetc(stdin)) != '\n' && carTemp != EOF && i < nbCar-1 ) { chaine[i] = carTemp; ++i; } /* marquage de la fin de la chaîne */ chaine[i] = '\0'; /* si il y a eu une erreur de lecture */ if (carTemp == EOF) { err = 2; } /* si des caractères on été laissés dans le buffer */ else if (carTemp != '\n') { err = 1; while ( (carTemp = fgetc(stdin)) != '\n' && carTemp != EOF ) { } } /* si tout s'est passé normalement */ else { err = 0; } } return err; } /* * readInteger * * Lit 10 caractères maximum sur stdin et stocke le nombre entier correspondant * à l'adresse p_nb * Le buffer de stdin est vide après l'appel de la fonction * * * Retour : * - si la lecture s'est passée correctement : 0 * - si le nombre dépasse la capacité d'un long ou si plus * de 10 caractères sont lus : 1 * (dans le premier cas *p_nb est inchangé, * dans le deuxième *p_nb est borné à LONG_MIN ou LONG_MAX) * - si erreur de lecture ou si p_nb == NULL : 2 */ unsigned int readLong (long *p_nb) { int err; if (p_nb == NULL) { err = 2; } else { char chaineTemp[11]; char *p_carInv; unsigned int resLecture; resLecture = readString (chaineTemp, sizeof chaineTemp); /* si lecture impossible */ if (resLecture == 1) { err = 1; } /* si chaîne tronquée */ else if (resLecture == 2) { err = 2; } else { long resConversion; errno = 0; resConversion = strtol (chaineTemp, &p_carInv, 10); /* si débordement pendant la conversion */ if (errno == ERANGE) { *p_nb = resConversion; err = 1; } /* si saisie réussie */ else if (*p_carInv == '\0') { *p_nb = resConversion; err = 0; } /* si conversion impossible */ else { err = 2; } } } return err; } /* * readDouble * * Lit 50 caractères maximum sur stdin et stocke le nombre flottant * correspondant à l'adresse p_nb * Le buffer de stdin est vide après l'appel de la fonction * * * Retour : * - si la lecture s'est passée correctement : 0 * - si le nombre dépasse la capacité d'un double ou si plus * de 50 caractères sont lus : 1 * (dans le premier cas *p_nb est inchangé, * dans le deuxième *p_nb est borné à +/- HUGE_VAL) * - si erreur de lecture ou si p_nb == NULL : 2 */ unsigned int readDouble (double *p_nb) { int err; if (p_nb == NULL) { err = 2; } else { char chaineTemp[128]; char *p_carInv; unsigned int resLecture; resLecture = readString (chaineTemp, sizeof chaineTemp); /* si lecture impossible */ if (resLecture == 1) { err = 1; } /* si chaîne tronquée */ else if (resLecture == 2) { err = 2; } else { double resConversion; errno = 0; resConversion = strtod (chaineTemp, &p_carInv); /* si débordement pendant la conversion */ if (errno == ERANGE) { *p_nb = resConversion; err = 1; } /* si saisie réussie */ else if (*p_carInv == '\0') { *p_nb = resConversion; err = 0; } /* si conversion impossible */ else { err = 2; } } } return err; }