Twitter iPhone pliant OnePlus 12 PS5 Disney+ Orange Livebox Windows 11 ChatGPT

Commentaires sur code source (long)

48 réponses
Avatar
Eddahbi Karim
Bonjour à tous,

J'suis rentré de vacanes et me revoici avec mes exos de C. Cette fois ci
crée une structure pour stocker les informations d'un vol.

Si vous avez tout commentaire sur le code, de manière à l'améliorer,
faites en part :-).

/*-8<-----------------------------------------------------------------

flight_reservation.c -- This program simulate a flight reservation

Author : Eddahbi Karim
E-mail : non.tu.ne.me.connais.pas.spavrai@ifrance.com Nick :
ThE_TemPLaR (newsgroups/Forums)

----------------------------------------------------------------------

Usage : Launch the program and enter the airport codes,
the flight number, the starting time and the arrival time.

Warning : Time must contain 2 digits : 2 digits. Not more, not
less.

----------------------------------------------------------------->8-*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>

/*--------------------------------------------------------------------

USAGE : Calculate the first dimension of a two dimensions array

PARAMETER : Two dimensional array

--------------------------------------------------------------------*/

#define FIRST_DIM_SIZE(array) sizeof((array)) / sizeof((array[0]))

/************************Structures***********************************

Reservation

Contains :
- flight_nb[6] : The flight number ( 4 digits max )
- orig_air_code[5] : The origin airport code ( 3 letters )
- dest_air_code[5] : The destination airport code ( 3 letters )
- start_time[7] : Starting time [2 digits : 2 digits]
- end_time[7] : Arrival time [2 digits : 2 digits]

*********************************************************************/

typedef struct {
char flight_nb[6];
char orig_air_code[5];
char dest_air_code[5];
char start_time[7];
char end_time[7];
} reservation;

/*********************************************************************

NAME : wipestring( string )

USAGE : Wipe useless values from the string...

PARAMETERS : char const *string to wipe...

*********************************************************************/

static void
wipestring (char const *string)
{
/* We search a '\n' character */
char *p = strchr (string, '\n');

/* We found it, we replace it by '\0' */ if (p)
{
*p = '\0';
}

/* We don't find it, so we get everything pending in stdin */ else
{
int c;

while ((c = getchar ()) != '\n' && c != EOF) {
}
}
}

/*********************************************************************

NAME : getstring ( string, size )

USAGE : Take the user input and verify it...

PARAMETERS :
- The string to check and to fill if the user enter something - The
size of the string

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
getstring (char *string, size_t size) {
/* The error number */
int err = EXIT_SUCCESS;

/* Check if there's an input */
if (fgets (string, (int) size, stdin) == NULL) {
(void) printf ("Input Error\n");
err = EXIT_FAILURE;
}

else
{
/* Is the input too large ? */
if ( strchr(string, '\n') == NULL )
{
(void) printf("Input too large.\n");
wipestring(string);
err = EXIT_FAILURE;
}

/* If we got a '\n', does he enter something ? */ if ( err ==
EXIT_SUCCESS )
{

/* Wipe useless values */
wipestring (string);

if (*string == '\0')
{
(void) printf ("No input\n");
err = EXIT_FAILURE;
}

}
}

return err;
}

/*********************************************************************

NAME : get_answer( *string, input_size )

USAGE : Print an input area with a space determined by the size of
the value to take and take the value.

PARAMETERS :
- The string to store the input.
- The size of this input.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
get_answer ( char *string, size_t input_size ) {
/* Exit status */
int err = EXIT_SUCCESS;

/* Variable used for repetitions */
size_t i = 0;

/* If we can't write anything in the string, this is useless */ #ifdef
DEBUG
if ( input_size < 3 )
{
(void) fprintf(stderr, "Input size allocated too small !"); err =
EXIT_FAILURE;
} else
#endif /* DEBUG */

{

/* Information about the number of char authorized */ (void)
printf("(%d char max)", (int) input_size - 2);

(void) printf("[");

/* sizeof returns the real size of an array, but for a string
we got 2 reserved places ( "string\n\0" ) */

/* Design the input area */
for (i = 0; i < input_size - 2; i++ ) {
(void) printf("-");
}

(void) printf("]");

/* stdin got ( input_size - 2 ) + 1 char, to put the user
inside the input area we go (input_size - 1) chars back */

/* Put the user inside the input area */ for (i = 0; i <
input_size - 1; i++ ) {
(void) printf("\b");
}


}

/* If nothing is wrong, grab the user value */ if ( err ==
EXIT_SUCCESS )
{
err = getstring(string, input_size);
}

return err;

}

/*********************************************************************

NAME : checkcode ( *string, input_size )

USAGE : Check the airport code entered by the user.

PARAMETERS :
- The airport code
- Its size.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checkcode ( char *string, size_t input_size ) {
/* Exit status */
int err = EXIT_SUCCESS;

/* The code number */
int number = 0;

/* The airport codes */
char codes[][5] = { "JPU", "NYC", "TYO", "TXL", "LCY", "HKG" };

#ifdef DEBUG

/* We check if the pointer points to something */ if ( string == NULL
)
{
(void) fprintf(stderr, "Invalid string pointer"); err =
EXIT_FAILURE;
}

/* The input_size must be equal to 5 (XXX\n\0) */ else if ( input_size
!= 5 )
{
(void) fprintf(stderr, "Input under/oversized."); err =
EXIT_FAILURE;
} else

#endif /* DEBUG*/

/* We get the airport code */
if ( err == EXIT_SUCCESS )
err = get_answer(string, input_size);

/* We check if the code is correct */ if ( err == EXIT_SUCCESS )
{
/* We reset the exit status */
err = EXIT_FAILURE;

/* The code is compared to each code in the code database */ for
(number = 0; number < FIRST_DIM_SIZE(string) + 1 &&
err != EXIT_SUCCESS; number++)
{
if ( strcmp(string, codes[number]) == 0 )
err = EXIT_SUCCESS;
}

/* If the user entered a wrong code, say it to him */ if ( err ==
EXIT_FAILURE )
(void) printf("Wrong airport code");
}

return err;
}

/*********************************************************************

NAME : checktime ( *string, input_size )

USAGE : Check if the user entered a valid time.

PARAMETERS :
- Time entered by the user
- Input size

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checktime (char *string, size_t input_size) {
/* Exit status */
int err = EXIT_SUCCESS;

/* Time values : Hour and minutes */
unsigned short int time[2] = { 0, 0 };

/* Debug : We check if the pointer is valid */ #ifdef DEBUG
if ( string == NULL )
{
(void) fprintf(stderr, "Invalid string pointer.\n"); err =
EXIT_FAILURE;
}

/* Debug : We check if the input_size is correct
It must be 7 ( xx:xx\n\0 ) */
else if ( input_size != 7 )
{
(void) fprintf(stderr, "Input under/oversized. Must be 7.\n"); err
= EXIT_FAILURE;
}
#endif /* DEBUG */

/* We get the time */
err = get_answer(string, input_size);

/* We verify if the user put the separator */ if ( string[2] != ':' )
{
(void) puts("Wrong separator or not placed correctly"); err =
EXIT_FAILURE;
}

/* We check if the user doesn't enter a letter at the end */ else if (
isdigit(string[4]) == 0 )
{
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* We check if the user entered two numbers */ else if (
sscanf(string, "%02hu:%02hu", &time[0], &time[1]) != 2 ) {
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* Are the time values correct ? */
else if ( ( time[0] > 23 ) || ( time[1] > 59 ) ) {
(void) puts("Wrong time, the maximal value for the hour is 23");
err = EXIT_FAILURE;
}

return err;

}

/*********************************************************************

NAME : ask ( *client_fl )

USAGE : Take the principal informations about the flight and do
some basic check.

PARAMETER : The client reservation data structure.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
ask ( reservation *client_fl )
{
/* Error status */
int err = EXIT_SUCCESS;

assert( client_fl != NULL );

/* We check if the pointer point to something */ if ( client_fl ==
NULL )
{
(void) fprintf(stderr, "Data structure pointer client_fl is
invalid"); err = EXIT_FAILURE;
}

/* If everything is ok, we ask the first question */ else {
(void) puts("What's the starting airport code :");

err = checkcode(client_fl->orig_air_code,
sizeof(client_fl->orig_air_code));
}

/* Ok ? Next question */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's the destination airport code :");

err = checkcode(client_fl->dest_air_code,
sizeof(client_fl->dest_air_code));
}

/* The flight number */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's your flight number :");

err = get_answer(client_fl->flight_nb,
sizeof(client_fl->flight_nb));
}

/* Starting and arrival time */
if ( err == EXIT_SUCCESS )
{
(void) puts("The flight will start at : ( Valid times are 00:00 ->
23:59 )"); err = checktime(client_fl->start_time,
sizeof(client_fl->start_time));
}

if ( err == EXIT_SUCCESS )
{
(void) puts("The plane will arrive at : ( Valid times are 00:00 ->
23:59 )"); err = checktime(client_fl->end_time,
sizeof(client_fl->end_time));
}

/* If everything is ok, we print the user's flight information */ if (
err == EXIT_SUCCESS )
{
(void) printf("You start from | %s\n"
"You'll fly to | %s\n"
"Your flight number is | %s\n"
"The plane will lift off at | %s\n"
"The plane will arrive at | %s\n",
client_fl->orig_air_code,
client_fl->dest_air_code,
client_fl->flight_nb,
client_fl->start_time,
client_fl->end_time);
}

return err;

}

/*********************************************************************

NAME : aircodes ( void )

USAGE : Display program version and airport codes.

*********************************************************************/

static void
aircodes ( void )
{
(void) puts("Flight reservation v0.1"); (void)
puts("---------------------------------------------------------");
(void) puts("Airport codes :");
(void) printf("\nJPU - Paris La Defense\n"
"NYC - New York Multiple City Code\n" "TYO - Tokyo Narita\n"
"TXL - Berlin Tegel\n"
"LCY - London City\n"
"HKG - Hong Kong Intl\n");
(void)
printf("---------------------------------------------------------\n\n");
}

int main ( void )
{
/* Final exit status */
int err = EXIT_SUCCESS;

/* The data structure which contains client flight informations */
reservation client_fl = {{0}, {0}, {0}, {0}, {0}};

/* Display the airport codes */
aircodes();

/* Get the client flight informations */ (void) puts("Welcome.");

err = ask( &client_fl );

return err;
}

8 réponses

1 2 3 4 5
Avatar
Eddahbi Karim
Bonjour/Bonsoir,

J'ai remodelé ma fonction pour récupérer ce que rentre l'utilisateur.

La voici :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ggets/ggets.h"

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = EXIT_SUCCESS, NOMEM = EXIT_FAILURE};

int fggets(char **ln, FILE *f)
{
/* The current size and the size of the line read */
int cursize, readsize;

/* The buffer to store the input, the variable to test memory
allocations result, the read pointer position, the last char */
char *buffer, *temp, *readpoint, *crlocn;

*ln = NULL;

/* Can't allocate the memory, quit */
if (NULL == (buffer = malloc(INITSIZE)))
{
return NOMEM;
}

/* Initialize sizes variables */
cursize = readsize = INITSIZE;

/* For the moment, input read and stored are the same */
readpoint = buffer;

*buffer = '';

/* We check if we can get the current line in the input */
if (NULL == fgets(readpoint, readsize, f))
{
free(buffer);
return EOF;
}

/* We can't locate any 'n', the size allocated is too small */
while (NULL == (crlocn = strchr(readpoint, 'n')))
{

/* We read the next 128 char + ' */
readsize = DELTASIZE + 1;

/* The size of the line will be 128 chars bigger */
cursize = cursize + DELTASIZE;

if (NULL == (temp = realloc(buffer, (size_t)cursize)))
{
/* ran out of memory */

/* Give at last the part read from the input */
*ln = buffer;
return NOMEM;
}

/* Reallocate "buffer" memory */
buffer = temp;

/* Reposition the pointer to continue */
readpoint = buffer + (cursize - DELTASIZE - 1);


/* Can we get the next part of the line ? */
if (NULL == fgets(readpoint, readsize, f))
{
/* We can't ? place a '' at the end of the buffer */
crlocn = strchr(buffer, '');
break;
}
}

/* Strip the 'n' */
*crlocn = '';

/* Get the difference between
the real size and the size allocated */

readsize = crlocn - buffer;

/* Reallocate less memory. */
if (NULL == (temp = realloc(buffer, (size_t)readsize + 1)))
*ln = buffer; /* without reducing it */
else
*ln = temp;
return OK;
}

static int
getstring (char *string, size_t size)
{
/* The error number */
int err = EXIT_SUCCESS;

/* The fggets return value */
int ret_fggets = 0;

/* Variable to store and test the user input */
char *user_input = NULL;

/* We try to get the user input and check what fggets returns */
if ( EXIT_SUCCESS != ( ret_fggets = fggets(&user_input, stdin) ) )
{
/* Get an EOF */
if ( ret_fggets == EOF )
{
(void) fprintf(stderr, "EOF before reading anythingn");
(void) puts("Can't get anything from the input");
err = EXIT_FAILURE;
}

/* The second possible return in this case is NOMEM */
else
{
(void) fprintf(stderr, "Ran out of memoryn");
(void) puts("No more memory available. Stop.");
err = EXIT_FAILURE;
}
}

/* We got the user input, now we check its validity */
else
{
/* The first char is the last char :
The user entered nothing */
if ( *user_input == '' )
{
(void) fprintf(stderr, "No inputn");
(void) puts("Enter something or go away !");
err = EXIT_FAILURE;
}

/* Does the user follow the max char limit ? */
else if ( strlen(user_input) > size - 1)
{
(void) fprintf(stderr, "Input too large !n");
(void) printf("Only %d char allowedn", (int) size - 1);
err = EXIT_FAILURE;
}
}

/* Everything is ok, copy the user input into the given string */
if ( err == EXIT_SUCCESS )
strncpy(user_input, string, (size - 1));

/* In both cases, free the memory */
free(user_input);

return err;
}


int main ( void )
{

int err = EXIT_SUCCESS;
char test[5] = {0};
char test2[32] = {0};

(void) printf("Insert something : ");
(void) fflush(stdout);

err = getstring(test, sizeof(test));

if ( err == EXIT_SUCCESS )
{
(void) printf("Insert something : ");
(void) fflush(stdout);
err = getstring(test2, sizeof(test2));
}

return err;

}

Voilà, j'aimerais savoir si je pourrais améliorer ce code.

Merci beaucoup.
Avatar
Bertrand Mollinier Toublet
Eddahbi Karim wrote:
Bonjour/Bonsoir,


Salut,


J'ai remodelé ma fonction pour récupérer ce que rentre l'utilisateur.



Content de voir que tu ne perds pas ton temps.
La voici :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ggets/ggets.h"

...

tu avais bien note le paragraphe suivant dans le fichier original ?
/* File ggets.c - goodgets is a safe alternative to gets */
/* By C.B. Falconer. Public domain 2002-06-22 */
/* attribution appreciated. */

Bref, c'est toi qui voit ce que tu fait avec ton code, mais si tu le
distribue, je suis que Chuck Falconer apprecierait une attribution.

#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

enum {OK = EXIT_SUCCESS, NOMEM = EXIT_FAILURE};

int fggets(char **ln, FILE *f)
{
/* The current size and the size of the line read */
int cursize, readsize;

/* The buffer to store the input, the variable to test memory
allocations result, the read pointer position, the last char */
char *buffer, *temp, *readpoint, *crlocn;

*ln = NULL;
Aaaah, c'est-t-y tout de meme pas mieux comme ca ?


Coupe du code qui me parait ok.

/* Does the user follow the max char limit ? */
else if ( strlen(user_input) > size - 1)
{
(void) fprintf(stderr, "Input too large !n");
(void) printf("Only %d char allowedn", (int) size - 1);
err = EXIT_FAILURE;


Ouais, alors ca, j'ai toujours pas bien pige. C'est pas vraiment du
ressort de ce NG, plutot de fr.comp.interface.utilisateur, mais qu'est
ce que tu gagnes a effectivement limiter le nombre de caracteres entres
par l'utilisateur. Pourquoi pas ne pas les ignorer silencieusement
(moins disruptif), peut-etre en etant malin et en faisant sauter les
caracteres blancs en debut de ligne.
}
}

/* Everything is ok, copy the user input into the given string */
if ( err == EXIT_SUCCESS )
strncpy(user_input, string, (size - 1));

La, c'est un peu surcomplique, ton truc. Pour, j'imagine, eviter d'avoir

a gerer un pointeur vers de la memoire allouee dans ton programme (je
parle de celui retourne par fggets), tu fais une copie dans un autre
pointeur que tu vois comme etant un tableau de char allouee
statiquement. Rien n'empeche un programmeur X d'appeler ta fonction
getstring avec de la memoire allouee dynamiquement, auquel cas tu copies
de la memoire allouee dynamiquement dans de la memoire allouee
dynamiquement :-/ C'est un peu du gachis de CPU...
/* In both cases, free the memory */
free(user_input);

return err;
}

RAS sur le main.


Voilà, j'aimerais savoir si je pourrais améliorer ce code.

Repense ton interface...


Au fait, je suis le seul a etre harcele de faux mails de la part de
Microsoft ? Ca en fait 18 depuis ce matin :-/
--
Bertrand Mollinier Toublet
Blog: http://www.bmt.dnsalias.org/blog

Avatar
Eddahbi Karim

Content de voir que tu ne perds pas ton temps.


Je fais ça doucement quand même...

...
tu avais bien note le paragraphe suivant dans le fichier original ?
/* File ggets.c - goodgets is a safe alternative to gets */
/* By C.B. Falconer. Public domain 2002-06-22 */
/* attribution appreciated. */


Ça me pose un peu problème, car je peux pas vraiment le mettre sous GPL,
quelqu'un pourra supprimer le copyright :/
Il va falloir que je vois ça avec lui effectivement.

Bref, c'est toi qui voit ce que tu fait avec ton code, mais si tu le
distribue, je suis que Chuck Falconer apprecierait une attribution.


Comme chaque personne partageant son travail.


*ln = NULL;
Aaaah, c'est-t-y tout de meme pas mieux comme ca ?


Coupe du code qui me parait ok.


Vi, c'est ce qui était fait initialement.


/* Does the user follow the max char limit ? */
else if ( strlen(user_input) > size - 1)
{
(void) fprintf(stderr, "Input too large !n");
(void) printf("Only %d char allowedn", (int) size - 1);
err = EXIT_FAILURE;


Ouais, alors ca, j'ai toujours pas bien pige. C'est pas vraiment du
ressort de ce NG, plutot de fr.comp.interface.utilisateur, mais qu'est
ce que tu gagnes a effectivement limiter le nombre de caracteres entres
par l'utilisateur. Pourquoi pas ne pas les ignorer silencieusement
(moins disruptif), peut-etre en etant malin et en faisant sauter les
caracteres blancs en debut de ligne.


Quand j'ajoute get_answer (fonction que je vais vérifier de ce pas), y'a
une case comme ça qui apparait [---] ou les '-' sont définis selon la
taille de l'array.
Si la personne dépasse, on lui signale.
Maintenant c'est vrai que quitter de suite n'est peut être pas la
meilleure façon de faire, mais c'est mieux que d'avoir une entrée tronqué
(du point de vue utilisateur)

}
}

/* Everything is ok, copy the user input into the given string */
if ( err == EXIT_SUCCESS )
strncpy(user_input, string, (size - 1));

La, c'est un peu surcomplique, ton truc. Pour, j'imagine, eviter d'avoir

a gerer un pointeur vers de la memoire allouee dans ton programme (je
parle de celui retourne par fggets), tu fais une copie dans un autre
pointeur que tu vois comme etant un tableau de char allouee
statiquement. Rien n'empeche un programmeur X d'appeler ta fonction
getstring avec de la memoire allouee dynamiquement, auquel cas tu copies
de la memoire allouee dynamiquement dans de la memoire allouee
dynamiquement :-/ C'est un peu du gachis de CPU...


Je devrais peut être limiter ma fonction aux arrays.
Mon but est d'utiliser de la mémoire statique, et de faire du recyclage de
la mémoire dynamique.
Le seul moment ou une mémoire dynamique est importante, selon moi, c'est
quand on doit traiter tout ce l'utilisateur rentre.

De plus si on enlève la gestion de taille maximale et que le programmeur X
utilise ma fonction avec des variables dynamiques, on va se retrouver avec
des variables qui prennent de la mémoire, alors qu'on pourrait éviter ça.
Quand je compare le code entrée avec un code de 3 lettres, je voudrais que
l'utilisateur ne rentre que 3 lettres.

En bref, pour une entrée dynamique, je changerais de fonction :)

Repense ton interface...


Ok


Au fait, je suis le seul a etre harcele de faux mails de la part de
Microsoft ? Ca en fait 18 depuis ce matin :-/


C'est un virus, bien ficelé car juste lancé après l'attaque Blaster.
Résultat 750.000 personnes ont téléchargés un patch, qui n'en était pas
un.
Je suis content de ne pas être sous Windows.

--
ThE_TemPLaR


Avatar
Stephane Legras-Decussy
"Bertrand Mollinier Toublet"
a écrit dans le message
news:
Au fait, je suis le seul a etre harcele de faux mails de la part de
Microsoft ? Ca en fait 18 depuis ce matin :-/


veinard...environ 200 pour moi... ;-)

Avatar
Marc Lasson
Stephane Legras-Decussy wrote:
veinard...environ 200 pour moi... ;-)

Deux cents en deux heures, c'est vraiment lourd... Un comble pour un

utilisateur
de linux :/.

Avatar
Eddahbi Karim

Stephane Legras-Decussy wrote:
veinard...environ 200 pour moi... ;-)

Deux cents en deux heures, c'est vraiment lourd... Un comble pour un

utilisateur
de linux :/.


Ça monopolise les réseaux, je trouve ça très très lourd !
Enfin bon...

--
ThE_TemPLaR


Avatar
Eddahbi Karim
Bon voilà une nouvelle version de code source :

/*-8<-----------------------------------------------------------------

flight_reservation.c -- This program simulate a flight reservation

Author : Eddahbi Karim
E-mail :
Nick : ThE_TemPLaR (newsgroups/Forums)

----------------------------------------------------------------------

Usage : Launch the program and enter the airport codes,
the flight number, the starting time and the
arrival time.

Warning : Time must contain 2 digits : 2 digits. Not more, not
less.

----------------------------------------------------------------->8-*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "ggets.h"

/*--------------------------------------------------------------------

FIRST_DIM_SIZE -- Size of the first dimension in a two
dimensionnal array.

--------------------------------------------------------------------*/

#define FIRST_DIM_SIZE(array) (sizeof((array))/sizeof (*(array)))

/*--------------------------------------------------------------------

INIT_SIZE -- The initial buffers size.
It's 2 ^ 7 - 16. Helps malloc

--------------------------------------------------------------------*/

#define INITSIZE 112

/*--------------------------------------------------------------------

DELTA_SIZE -- Size allocated with realloc. It's 2 ^ 7.

--------------------------------------------------------------------*/

#define DELTASIZE (INITSIZE + 16)

/*--------------------------------------------------------------------

TIME_SIZE -- Number of chars allowed for the time in the user
input.

--------------------------------------------------------------------*/

#define TIME_SIZE 5

/*--------------------------------------------------------------------

CODE_SIZE -- Number of chars allow for an airport code

--------------------------------------------------------------------*/

#define CODE_SIZE 3

/*--------------------------------------------------------------------

Error status

--------------------------------------------------------------------*/

enum {OK = EXIT_SUCCESS, NOMEM = EXIT_FAILURE};

/************************Structures***********************************

NAME : Reservation

Contains :
- flight_nb : The flight number ( 4 digits max )
- orig_air_code : The origin airport code ( 3 letters )
- dest_air_code : The destination airport code ( 3 letters )
- start_time : Starting time [2 digits : 2 digits]
- end_time : Arrival time [2 digits : 2 digits]

*********************************************************************/

typedef struct {
char *flight_nb;
char *orig_air_code;
char *dest_air_code;
char *start_time;
char *end_time;
} reservation;

/************************Structures***********************************

NAME : codes

Contains :
- code : The airport code
- name : Its real name
- longitute : Its longitude
- latitude : Its lattitude

*********************************************************************/

struct codes {
char *code;
char *name;
double longitude;
double latitude;
} air_codes[] = {
{"JPU", "Paris La Défense", 48.8670, 2.3330},
{"NYC", "New York City", 40.714, -74.006},
{"TYO", "Tokyo Narita", 0.0, 0.0},
{"TXL", "Berlin Tegel", 0.0, 0.0},
{"LCY", "London City", 0.0, 0.0},
{"HKG", "Hong Kong Intl", 0.0, 0.0}
};

/*********************************************************************

NAME : fggets( **ln, *f )

USAGE : Get the user input

PARAMETERS :
- The buffer to store the user input
- The file containing the input

RETURNS :
- OK (EXIT_SUCCESS)
- NOMEM (EXIT_FAILURE)
- EOF

INFO :
- This function doesn't belong to me but I've modified it a bit.
If you have a bug report about this function send it to me.
If you want to use this function in your program, ask to :


*********************************************************************/

int fggets(char **const ln, FILE *const f)
{
/* The current size and the size of the line read */
int cursize, readsize;

/* The buffer to store the input, the variable to test memory
allocations result, the read pointer position, the last char */
char *buffer, *temp, *readpoint, *crlocn;

*ln = NULL;

/* Can't allocate the memory, quit */
if (NULL == (buffer = malloc(INITSIZE)))
{
return NOMEM;
}

/* Initialize sizes variables */
cursize = readsize = INITSIZE;

/* For the moment, input read and stored are the same */
readpoint = buffer;

*buffer = '';

/* We check if we can get the current line in the input */
if (NULL == fgets(readpoint, readsize, f))
{
free(buffer);
return EOF;
}

/* We can't locate any 'n', the size allocated is too small */
while (NULL == (crlocn = strchr(readpoint, 'n')))
{

/* We read the next 128 char + ' */
readsize = DELTASIZE + 1;

/* The size of the line will be 128 chars bigger */
cursize = cursize + DELTASIZE;

if (NULL == (temp = realloc(buffer, (size_t)cursize)))
{
/* ran out of memory */

/* Give at last the part read from the input */
*ln = buffer;
return NOMEM;
}

/* Reallocate "buffer" memory */
buffer = temp;

/* Reposition the pointer to continue */
readpoint = buffer + (cursize - DELTASIZE - 1);


/* Can we get the next part of the line ? */
if (NULL == fgets(readpoint, readsize, f))
{
/* We can't ? place a '' at the end of the buffer */
crlocn = strchr(buffer, '');
break;
}
}

/* Strip the 'n' */
*crlocn = '';

/* Get the difference between
the real size and the size allocated */

readsize = crlocn - buffer;

/* Reallocate less memory. */
if (NULL == (temp = realloc(buffer, (size_t)readsize + 1)))
*ln = buffer; /* without reducing it */
else
*ln = temp;
return OK;
}

/*********************************************************************

NAME : getstring ( string, size )

USAGE : Check the user input and copy it to an array

PARAMETERS :
- The string
- The wanted size for the input

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
getstring (char **const user_input, int const size)
{
/* The error number */
int err = EXIT_SUCCESS;

/* The fggets return value */
int ret_fggets = 0;

/* Debug : We check if the pointer is
valid and if the size != 0 */

assert( (user_input != NULL) && ( size != 0 ) );


/* We try to get the user input and check what fggets returns */
if ( EXIT_SUCCESS != ( ret_fggets = fggets(user_input, stdin) ) )
{
/* Get an EOF */
if ( ret_fggets == EOF )
{
(void) fprintf(stderr, "EOF before reading anythingn");
(void) puts("Can't get anything from the input");
err = EXIT_FAILURE;
}

/* The second possible return in this case is NOMEM */
else
{
(void) fprintf(stderr, "Ran out of memoryn");
(void) puts("No more memory available. Stop.");
err = EXIT_FAILURE;
}
}

/* We got the user input, now we check its validity */
else
{
/* The first char is the last char :
The user entered nothing */
if ( *user_input == '' )
{
(void) fprintf(stderr, "No inputn");
(void) puts("Enter something or go away !");
err = EXIT_FAILURE;
}

/* Does the user follow the max char limit ? */
else if ( strlen(*user_input) > size)
{
(void) fprintf(stderr, "Input too large !n");
(void) printf("Only %d char allowedn", size);
err = EXIT_FAILURE;
}
}

return err;
}

/*********************************************************************

NAME : get_answer( *string, input_size )

USAGE : Print an input area with a space determined by the
programmer.

PARAMETERS :
- The string to store the input.
- The size wanted for the input.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
get_answer ( char **string, int const wanted_size )
{
/* Exit status */
int err = EXIT_SUCCESS;

/* Variable used for repetitions */
int i = 0;

/* We check if the pointer is valid */
assert( wanted_size > 2 );

/* Information about the number of char authorized */
(void) printf("(%d char max) ", (int) wanted_size);

(void) printf("[");

/* Design the input area */

/* We must print a '-' for each character allowed */
for (i = 0; i < wanted_size ; i++ )
{
(void) printf("-");
}

(void) printf("]");

/* stdin got wanted_size + 1 char, to put the user
inside the input area we go (wanted_size + 1) chars back */

/* Put the user inside the input area */
for (i = 0; i < wanted_size + 1; i++ )
{
(void) printf("b");
}

/* Force the display of this printf sequence */
(void) fflush(stdout);

/* If nothing is wrong, grab the user value */
if ( err == EXIT_SUCCESS )
err = getstring(string, wanted_size);


return err;

}

/*********************************************************************

NAME : checkcode ( *string )

USAGE : Check the airport code entered by the user.

PARAMETERS :
- The airport code

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checkcode ( char **const string )
{
/* Exit status */
int err = EXIT_SUCCESS;

/* The code number */
int number = 0;

/* Debug : We check if the pointer is valid */
assert( string != NULL );

/* We get the airport code */
if ( err == EXIT_SUCCESS )
err = get_answer(string, CODE_SIZE);

/* We check if the code is correct */
if ( err == EXIT_SUCCESS )
{
/* We reset the exit status */
err = EXIT_FAILURE;


/* The code is compared to each code in the code database */
for (number = 0; number < FIRST_DIM_SIZE(air_codes) + 1 &&
err != EXIT_SUCCESS; number++)
{
if ( strcmp(*string, air_codes[number].code) == 0 )
err = EXIT_SUCCESS;
}

/* If the user entered a wrong code, say it to him */
if ( err == EXIT_FAILURE )
(void) printf("Wrong airport coden");
}

return err;
}

/*********************************************************************

NAME : checktime ( *string )

USAGE : Check if the user entered a valid time.

PARAMETERS :
- Time entered by the user

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
checktime (char **const string)
{
/* Exit status */
int err = EXIT_SUCCESS;

/* Time values : Hour and minutes */
unsigned short int time[2] = { 0, 0 };

/* Debug : We check if the pointer is valid */
assert( string != NULL );

/* We get the time */
err = get_answer(string, TIME_SIZE);

/* We verify if the user put the separator */
if ( *(*string+2) != ':' )
{
(void) fprintf(stderr, "Wrong separator : %c isn't ':'n", *(*string+2));
(void) puts("Wrong separator or not placed correctly");
err = EXIT_FAILURE;
}

/* We check if the user doesn't enter a letter at the end */
else if ( isdigit((*string)[4]) == 0 )
{
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* We check if the user entered two numbers */
else if ( sscanf(*string, "%02hu:%02hu", &time[0], &time[1]) != 2 )
{
(void) puts("Wrong values");
err = EXIT_FAILURE;
}

/* Are the time values correct ? */
else if ( ( time[0] > 23 ) || ( time[1] > 59 ) )
{
(void) puts("Wrong time, the maximal value for the hour is 23");
(void) puts("And the maximal value for the minutes is 59");
err = EXIT_FAILURE;
}

return err;

}

/*********************************************************************

NAME : ask ( *client_fl )

USAGE : Take the principal informations about the flight and do
some basic check.

PARAMETER : The client reservation data structure.

RETURNS (int) :
- EXIT_SUCCESS
- EXIT_FAILURE

*********************************************************************/

static int
ask ( reservation *const client_fl )
{
/* Error status */
int err = EXIT_SUCCESS;

/* The flight number size */
int flight_size = 4;

/* We check the client flight data structure */
assert( client_fl != NULL );

/* If everything is ok, we ask the first question */
(void) puts("What's the starting airport code :");

err = checkcode(&client_fl->orig_air_code);

/* Ok ? Next question */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's the destination airport code :");

err = checkcode(&client_fl->dest_air_code);
}

/* The flight number */
if ( err == EXIT_SUCCESS )
{
(void) puts("What's your flight number :");

err = get_answer(&client_fl->flight_nb, flight_size);
}

/* Starting and arrival time */
if ( err == EXIT_SUCCESS )
{
(void) puts("The flight will start at : ( Valid times are 00:00 -> 23:59 )");
err = checktime(&client_fl->start_time);
}

if ( err == EXIT_SUCCESS )
{
(void) puts("The plane will arrive at : ( Valid times are 00:00 -> 23:59 )");
err = checktime(&client_fl->end_time);
}

/* If everything is ok, we print the user's flight information */
if ( err == EXIT_SUCCESS )
{
(void) printf("You start from | %sn"
"You'll fly to | %sn"
"Your flight number is | %sn"
"The plane will lift off at | %sn"
"The plane will arrive at | %sn",
client_fl->orig_air_code,
client_fl->dest_air_code,
client_fl->flight_nb,
client_fl->start_time,
client_fl->end_time);
}

free(client_fl->orig_air_code);
free(client_fl->dest_air_code);
free(client_fl->flight_nb);
free(client_fl->start_time);
free(client_fl->end_time);

return err;

}

/*********************************************************************

NAME : aircodes ( void )

USAGE : Display program version and airport codes.

*********************************************************************/

static void
aircodes ( void )
{
/* Position in the structure array */
int position = 0;

(void) puts("Flight reservation v0.1");
(void) puts("---------------------------------------------------------");
(void) puts("Airport codes :");
for (position = 0; position < FIRST_DIM_SIZE(air_codes); position++)
{
(void) printf("%s - %sn",
air_codes[position].code, air_codes[position].name);
}
(void) printf("---------------------------------------------------------nn");
}


int main ( void )
{
/* Final exit status */
int err = EXIT_SUCCESS;

/* The data structure which contains client flight informations */
reservation client_fl = {NULL, NULL, NULL, NULL, NULL};

/* Display the airport codes */
aircodes();

/* Get the client flight informations */
(void) puts("Welcome.");

err = ask( &client_fl );

return err;
}

Pour la compilation modulaire je vais voir, sinon si vous voyez quelque
chose qui ne va pas ?

Les latitudes et longitudes sont là, car je compte implémenter la fonction
donné par l'exercice de Delahaye ;)

Voilà,
ThE_TemPLaR
Avatar
Eddahbi Karim

En voyant le post de Marc Boyer (bordel d'unsigned :)), j'ai ajouté -W
comme l'indiquait Gabriel Dos Reis, ça m'a permit de faire quelques
changements.

static int
getstring (char **const user_input, unsigned int const size)

/* Variable used for repetitions */
unsigned int i = 0;


static int
get_answer ( char **string, unsigned int const wanted_size )
{
/* Variable used for repetitions */
unsigned int i = 0;



/* The code number */
unsigned int number = 0;



--
ThE_TemPLaR

1 2 3 4 5