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 )
{
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);
}
/* 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");
}
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;
}
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 :");
/* 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);
}
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.");
In 'fr.comp.lang.c', Laurent Wacrenier <lwa@ teaser . fr> wrote:
Bertrand Mollinier Toublet écrit:
Mais nous sommes bien d'accord. Et c'est ce que je dis, non ?
Oui, désolé, je n'avais pas bien vu la forme intéro-négative indirecte de ta phrase.
Mal à la tête...
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html <blank line> FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Emmanuel Delahaye
In 'fr.comp.lang.c', Bertrand Mollinier Toublet wrote:
void foo(int *a) { int *tmp;
tmp = realloc(a, 10); if (NULL != tmp) { a = tmp; } }
Si la zone de memoire filee par realloc est differente de la zone de memoire originale, au retour de la fonction, l'appelant a un pointeur vers une zone de memoire non valide :-(
J'ai mis du temps a m'en rendre compte, et j'aurais ete sauve par une declaration du genre:
void foo(int *const a) { ... }
Ce que j'essaye de faire systématiquement... Ca me vaut quelques railleries, mais je sais que j'ai raison...
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html <blank line> FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
In 'fr.comp.lang.c', Bertrand Mollinier Toublet
<bertrand.mollinierNOSPAMtoublet@enst-bretagne.fr> wrote:
void foo(int *a)
{
int *tmp;
tmp = realloc(a, 10);
if (NULL != tmp) { a = tmp; }
}
Si la zone de memoire filee par realloc est differente de la zone de
memoire originale, au retour de la fonction, l'appelant a un pointeur
vers une zone de memoire non valide :-(
J'ai mis du temps a m'en rendre compte, et j'aurais ete sauve par une
declaration du genre:
void foo(int *const a)
{
...
}
Ce que j'essaye de faire systématiquement... Ca me vaut quelques railleries,
mais je sais que j'ai raison...
--
-ed- emdelYOURBRA@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
In 'fr.comp.lang.c', Bertrand Mollinier Toublet wrote:
void foo(int *a) { int *tmp;
tmp = realloc(a, 10); if (NULL != tmp) { a = tmp; } }
Si la zone de memoire filee par realloc est differente de la zone de memoire originale, au retour de la fonction, l'appelant a un pointeur vers une zone de memoire non valide :-(
J'ai mis du temps a m'en rendre compte, et j'aurais ete sauve par une declaration du genre:
void foo(int *const a) { ... }
Ce que j'essaye de faire systématiquement... Ca me vaut quelques railleries, mais je sais que j'ai raison...
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html <blank line> FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Eddahbi Karim
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
gcc -Wall -Werror -pedantic -pedantic-errors
Voila, ThE_TemPLaR
Qu'est ce qui ne va pas avec:
reservation client_fl = {0};
?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur
AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
gcc -Wall -Werror -pedantic -pedantic-errors
Voila, ThE_TemPLaR
Bertrand Mollinier Toublet
Eddahbi Karim wrote:
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
gcc -Wall -Werror -pedantic -pedantic-errors
Tiens c'est marrant, j'ai vu ce probleme la pas plus tard qu'aujourd'hui
meme sur comp.lang.c. Apparement, le consensus sur c.l.c est que c'est un message incorrect (dans la mesure ou il n'est pas necessaire) de gcc.
Libre a toi de t'en tenir a reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de compilateur" <grin> -- Bertrand Mollinier Toublet [A] Top-posting. [Q] What's the most annoying thing on Usenet ?
Eddahbi Karim wrote:
Qu'est ce qui ne va pas avec:
reservation client_fl = {0};
?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur
AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
gcc -Wall -Werror -pedantic -pedantic-errors
Tiens c'est marrant, j'ai vu ce probleme la pas plus tard qu'aujourd'hui
meme sur comp.lang.c. Apparement, le consensus sur c.l.c est que c'est
un message incorrect (dans la mesure ou il n'est pas necessaire) de gcc.
Libre a toi de t'en tenir a
reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de
compilateur" <grin>
--
Bertrand Mollinier Toublet
[A] Top-posting.
[Q] What's the most annoying thing on Usenet ?
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Le problème est :
AVERTISSEMENT : Accolades manquantes autour de l'initialiseur AVERTISSEMENT : (près de l'initialisation pour « client_fl.flight_nb »)
gcc -Wall -Werror -pedantic -pedantic-errors
Tiens c'est marrant, j'ai vu ce probleme la pas plus tard qu'aujourd'hui
meme sur comp.lang.c. Apparement, le consensus sur c.l.c est que c'est un message incorrect (dans la mesure ou il n'est pas necessaire) de gcc.
Libre a toi de t'en tenir a reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de compilateur" <grin> -- Bertrand Mollinier Toublet [A] Top-posting. [Q] What's the most annoying thing on Usenet ?
Eddahbi Karim
Libre a toi de t'en tenir a reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de compilateur" <grin>
Changer de compilateur, je prends quoi icc ? :) Et de toute façon, splint me resortira le warning.
Est ce que l'initialisation de tous les éléments est plus rapide avec la première manière ?
Voila, ThE_TemPLaR
Libre a toi de t'en tenir a
reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de
compilateur" <grin>
Changer de compilateur, je prends quoi icc ? :)
Et de toute façon, splint me resortira le warning.
Est ce que l'initialisation de tous les éléments est plus rapide avec la
première manière ?
Libre a toi de t'en tenir a reservation client_fl - { {0}, {0}, etc... };
ou bien d'appliquer l'adage: "Mauvais compilateur, changer de compilateur" <grin>
Changer de compilateur, je prends quoi icc ? :) Et de toute façon, splint me resortira le warning.
Est ce que l'initialisation de tous les éléments est plus rapide avec la première manière ?
Voila, ThE_TemPLaR
Eddahbi Karim
N'oublie pas de liberer la ligne allouee par ggets a un moment donne. Je te recommande l'utilisation du module memtrack, en ligne (d'ici quelques heures) sur http://www.bmt.dnsalias.org/employment, que j'ai adapte du bouquin C Unleashed, ou il etait introduit par Richard Heathfield.
Alors j'ai tenté de comprendre ce que faisait cette fonction (Y'a interet si je l'intègre à mon source).
Donc j'ai essayé de commenter un peu plus le code source, de manière à éclaircir les parties que je ne comprenais pas vraiment.
Mais je n'arrive pas à comprendre la fin.
Je n'ai pas encore entamé l'allocation et ré-allocation de mémoire dans mon bouquin par ailleurs.
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */ #define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f) { /* The current size and the size read */ int cursize, rdsize;
/* - The temporary buffer used to store the input - Store value returns by memory allocations and reallocations - Store what has been actually read - Used to locate n and (?) */ char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */ *ln = NULL;
/* If the memory allocation missed, quit the program */ if (NULL == (buffer = malloc(INITSIZE))) return NOMEM;
/* For the moment, input read and stored are the same */ rdpoint = buffer;
/* Like *ln, initialize the buffer */ *buffer = ' ';
/* We check if we can get the current line in the input */ if (NULL == fgets(rdpoint, rdsize, f)) { free(buffer); return EOF; } /* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */ while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */ rdsize = DELTASIZE + 1; /* allow for a final ' ' */ cursize += DELTASIZE;
/* -(EK)- No memory ? */ if (NULL == (temp = realloc(buffer, (size_t)cursize))) { /* ran out of memory */
/* Give at last the part read from the input */ *ln = buffer; /* partial line, next call may fail */ return NOMEM; }
/*****?*****/ buffer = temp; /* Read into the ' ' up */ rdpoint = buffer + (cursize - DELTASIZE - 1); /*****?*****/
/* get the next piece of this line */ /* Note 1 */ if (NULL == fgets(rdpoint, rdsize, f)) { /* early EOF encountered */ crlocn = strchr(buffer, ' '); break; } } /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */ /* Fin Note 1 */
rdsize = crlocn - buffer; /* Note 2 */ if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) { *ln = buffer; /* without reducing it */ return OK; } *ln = temp; /* Fin Note 2 */ return OK; } /* fggets */ /* End of ggets.c */
|-------------------------------------------|
Note 1 : On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn ' ' ?
Note 2 : Est ce plus avantageux de faire ça au lieu de :
if ( expression ) a = b; else a = c;
return OK;
?
Merci :), Voila, ThE_TemPLaR
N'oublie pas de liberer la ligne allouee par ggets a un moment donne. Je
te recommande l'utilisation du module memtrack, en ligne (d'ici quelques
heures) sur http://www.bmt.dnsalias.org/employment, que j'ai adapte du
bouquin C Unleashed, ou il etait introduit par Richard Heathfield.
Alors j'ai tenté de comprendre ce que faisait cette fonction (Y'a interet
si je l'intègre à mon source).
Donc j'ai essayé de commenter un peu plus le code source, de manière à
éclaircir les parties que je ne comprenais pas vraiment.
Mais je n'arrive pas à comprendre la fin.
Je n'ai pas encore entamé l'allocation et ré-allocation de mémoire dans
mon bouquin par ailleurs.
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f)
{
/* The current size and the size read */
int cursize, rdsize;
/*
- The temporary buffer used to store the input
- Store value returns by memory allocations and reallocations
- Store what has been actually read
- Used to locate n and (?)
*/
char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */
*ln = NULL;
/* If the memory allocation missed, quit the program */
if (NULL == (buffer = malloc(INITSIZE)))
return NOMEM;
/* For the moment, input read and stored are the same */
rdpoint = buffer;
/* Like *ln, initialize the buffer */
*buffer = ' ';
/* We check if we can get the current line in the input */
if (NULL == fgets(rdpoint, rdsize, f)) {
free(buffer);
return EOF;
}
/* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */
while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */
rdsize = DELTASIZE + 1; /* allow for a final ' ' */
cursize += DELTASIZE;
/* -(EK)- No memory ? */
if (NULL == (temp = realloc(buffer, (size_t)cursize))) {
/* ran out of memory */
/* Give at last the part read from the input */
*ln = buffer; /* partial line, next call may fail */
return NOMEM;
}
/*****?*****/
buffer = temp;
/* Read into the ' ' up */
rdpoint = buffer + (cursize - DELTASIZE - 1);
/*****?*****/
/* get the next piece of this line */
/* Note 1 */
if (NULL == fgets(rdpoint, rdsize, f)) {
/* early EOF encountered */
crlocn = strchr(buffer, ' ');
break;
}
} /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */
/* Fin Note 1 */
rdsize = crlocn - buffer;
/* Note 2 */
if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) {
*ln = buffer; /* without reducing it */
return OK;
}
*ln = temp;
/* Fin Note 2 */
return OK;
} /* fggets */
/* End of ggets.c */
|-------------------------------------------|
Note 1 :
On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn ' ' ?
Note 2 :
Est ce plus avantageux de faire ça au lieu de :
N'oublie pas de liberer la ligne allouee par ggets a un moment donne. Je te recommande l'utilisation du module memtrack, en ligne (d'ici quelques heures) sur http://www.bmt.dnsalias.org/employment, que j'ai adapte du bouquin C Unleashed, ou il etait introduit par Richard Heathfield.
Alors j'ai tenté de comprendre ce que faisait cette fonction (Y'a interet si je l'intègre à mon source).
Donc j'ai essayé de commenter un peu plus le code source, de manière à éclaircir les parties que je ne comprenais pas vraiment.
Mais je n'arrive pas à comprendre la fin.
Je n'ai pas encore entamé l'allocation et ré-allocation de mémoire dans mon bouquin par ailleurs.
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */ #define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f) { /* The current size and the size read */ int cursize, rdsize;
/* - The temporary buffer used to store the input - Store value returns by memory allocations and reallocations - Store what has been actually read - Used to locate n and (?) */ char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */ *ln = NULL;
/* If the memory allocation missed, quit the program */ if (NULL == (buffer = malloc(INITSIZE))) return NOMEM;
/* For the moment, input read and stored are the same */ rdpoint = buffer;
/* Like *ln, initialize the buffer */ *buffer = ' ';
/* We check if we can get the current line in the input */ if (NULL == fgets(rdpoint, rdsize, f)) { free(buffer); return EOF; } /* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */ while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */ rdsize = DELTASIZE + 1; /* allow for a final ' ' */ cursize += DELTASIZE;
/* -(EK)- No memory ? */ if (NULL == (temp = realloc(buffer, (size_t)cursize))) { /* ran out of memory */
/* Give at last the part read from the input */ *ln = buffer; /* partial line, next call may fail */ return NOMEM; }
/*****?*****/ buffer = temp; /* Read into the ' ' up */ rdpoint = buffer + (cursize - DELTASIZE - 1); /*****?*****/
/* get the next piece of this line */ /* Note 1 */ if (NULL == fgets(rdpoint, rdsize, f)) { /* early EOF encountered */ crlocn = strchr(buffer, ' '); break; } } /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */ /* Fin Note 1 */
rdsize = crlocn - buffer; /* Note 2 */ if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) { *ln = buffer; /* without reducing it */ return OK; } *ln = temp; /* Fin Note 2 */ return OK; } /* fggets */ /* End of ggets.c */
|-------------------------------------------|
Note 1 : On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn ' ' ?
Note 2 : Est ce plus avantageux de faire ça au lieu de :
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */ #define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f) { /* The current size and the size read */ int cursize, rdsize;
/* - The temporary buffer used to store the input - Store value returns by memory allocations and reallocations - Store what has been actually read - Used to locate n and (?) */ char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */ *ln = NULL;
/* If the memory allocation missed, quit the program */ if (NULL == (buffer = malloc(INITSIZE))) return NOMEM;
/* For the moment, input read and stored are the same */ rdpoint = buffer;
/* Like *ln, initialize the buffer */ *buffer = ' ';
/* We check if we can get the current line in the input */ if (NULL == fgets(rdpoint, rdsize, f)) { free(buffer); return EOF; } /* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */ while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */ rdsize = DELTASIZE + 1; /* allow for a final ' ' */ cursize += DELTASIZE;
/* -(EK)- No memory ? */ if (NULL == (temp = realloc(buffer, (size_t)cursize))) { /* ran out of memory */
/* Give at last the part read from the input */ *ln = buffer; /* partial line, next call may fail */ return NOMEM; }
est *la* maniere de faire une reallocation. En effet, si tu faisais directement
foo = realloc(foo, size);
en cas d'erreur, realloc te renvoie NULL et tu viens de perdre le pointeur sur l'espace originalement alloue a foo.
/* Read into the ' ' up */ rdpoint = buffer + (cursize - DELTASIZE - 1);
Voyons voir si je peux te faire un schema des choses. A regarder avec une police de largeur fixe. |<-----rdsizeÞLTASIZE+1-------->| <---------------------------cursize--------------------------------->| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ^ ^ | | buffer rdpoint
/*****?*****/
/* get the next piece of this line */ /* Note 1 */ if (NULL == fgets(rdpoint, rdsize, f)) { /* early EOF encountered */ crlocn = strchr(buffer, ' '); break; } } /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */
Cette ligne est executee dans deux cas: a) terminaison normale du while. Ca veut dire que un 'n' a ete trouve dans la ligne et que crlocn pointe vers lui. Dans ce cas, la ligne ci-dessus efface le 'n', qui, a cause de la semantique de fgets est necessairement le dernier caractere de la ligne. b) terminaison anormale du while, qui n'arrive que dans le bloc ci-dessus, auquel cas crlocn pointe vers le ' ' final de la ligne, et ca ne peut pas faire de mal de le remplacer par un autre ' '.
Ca couvre tous les cas de figure de facon elegante, AMHA.
/* Fin Note 1 */
rdsize = crlocn - buffer; /* Note 2 */ if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) { *ln = buffer; /* without reducing it */ return OK; } *ln = temp; /* Fin Note 2 */
A propos de note, note que c'est a priori une reallocation en diminution, de facon a n'avoir alloue que la taille exactement necessaire pour tenir la ligne complete.
return OK; } /* fggets */ /* End of ggets.c */
|-------------------------------------------|
Note 1 : On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn > ' ' ?
Ma reponse est ci-dessus.
Note 2 : Est ce plus avantageux de faire ça au lieu de :
if ( expression ) a = b; else a = c;
return OK;
? Pas forcement. C'est le style de l'auteur, et c'est son droit...
-- Bertrand Mollinier Toublet "In regard to Ducatis vs. women, it has been said: 'One is a sexy thing that you've just got to ride, even if it breaks down a lot, costs a lot of money, and will probably try to kill you'. However, nowadays I can't seem to remember which one is which." -- Peer Landa
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f)
{
/* The current size and the size read */
int cursize, rdsize;
/*
- The temporary buffer used to store the input
- Store value returns by memory allocations and reallocations
- Store what has been actually read
- Used to locate n and (?)
*/
char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */
*ln = NULL;
/* If the memory allocation missed, quit the program */
if (NULL == (buffer = malloc(INITSIZE)))
return NOMEM;
/* For the moment, input read and stored are the same */
rdpoint = buffer;
/* Like *ln, initialize the buffer */
*buffer = ' ';
/* We check if we can get the current line in the input */
if (NULL == fgets(rdpoint, rdsize, f)) {
free(buffer);
return EOF;
}
/* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */
while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */
rdsize = DELTASIZE + 1; /* allow for a final ' ' */
cursize += DELTASIZE;
/* -(EK)- No memory ? */
if (NULL == (temp = realloc(buffer, (size_t)cursize))) {
/* ran out of memory */
/* Give at last the part read from the input */
*ln = buffer; /* partial line, next call may fail */
return NOMEM;
}
est *la* maniere de faire une reallocation. En effet, si tu faisais
directement
foo = realloc(foo, size);
en cas d'erreur, realloc te renvoie NULL et tu viens de perdre le
pointeur sur l'espace originalement alloue a foo.
/* Read into the ' ' up */
rdpoint = buffer + (cursize - DELTASIZE - 1);
Voyons voir si je peux te faire un schema des choses. A regarder avec
une police de largeur fixe.
|<-----rdsizeÞLTASIZE+1-------->|
<---------------------------cursize--------------------------------->|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^ ^
| |
buffer rdpoint
/*****?*****/
/* get the next piece of this line */
/* Note 1 */
if (NULL == fgets(rdpoint, rdsize, f)) {
/* early EOF encountered */
crlocn = strchr(buffer, ' ');
break;
}
} /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */
Cette ligne est executee dans deux cas:
a) terminaison normale du while. Ca veut dire que un 'n' a ete trouve
dans la ligne et que crlocn pointe vers lui. Dans ce cas, la ligne
ci-dessus efface le 'n', qui, a cause de la semantique de fgets est
necessairement le dernier caractere de la ligne.
b) terminaison anormale du while, qui n'arrive que dans le bloc
ci-dessus, auquel cas crlocn pointe vers le ' ' final de la ligne,
et ca ne peut pas faire de mal de le remplacer par un autre ' '.
Ca couvre tous les cas de figure de facon elegante, AMHA.
/* Fin Note 1 */
rdsize = crlocn - buffer;
/* Note 2 */
if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) {
*ln = buffer; /* without reducing it */
return OK;
}
*ln = temp;
/* Fin Note 2 */
A propos de note, note que c'est a priori une reallocation en
diminution, de facon a n'avoir alloue que la taille exactement
necessaire pour tenir la ligne complete.
return OK;
} /* fggets */
/* End of ggets.c */
|-------------------------------------------|
Note 1 :
On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn > ' ' ?
Ma reponse est ci-dessus.
Note 2 :
Est ce plus avantageux de faire ça au lieu de :
if ( expression )
a = b;
else
a = c;
return OK;
?
Pas forcement. C'est le style de l'auteur, et c'est son droit...
--
Bertrand Mollinier Toublet
"In regard to Ducatis vs. women, it has been said: 'One is a sexy thing
that you've just got to ride, even if it breaks down a lot, costs a lot
of money, and will probably try to kill you'. However, nowadays I can't
seem to remember which one is which." -- Peer Landa
#define INITSIZE 112 /* power of 2 minus 16, helps malloc */ #define DELTASIZE (INITSIZE + 16)
enum {OK = 0, NOMEM};
int fggets(char* *ln, FILE *f) { /* The current size and the size read */ int cursize, rdsize;
/* - The temporary buffer used to store the input - Store value returns by memory allocations and reallocations - Store what has been actually read - Used to locate n and (?) */ char *buffer, *temp, *rdpoint, *crlocn;
/* Don't use freed memory */ *ln = NULL;
/* If the memory allocation missed, quit the program */ if (NULL == (buffer = malloc(INITSIZE))) return NOMEM;
/* For the moment, input read and stored are the same */ rdpoint = buffer;
/* Like *ln, initialize the buffer */ *buffer = ' ';
/* We check if we can get the current line in the input */ if (NULL == fgets(rdpoint, rdsize, f)) { free(buffer); return EOF; } /* initial read succeeded, now decide about expansion */
/* We can't locate any 'n', the size allocated is too small */ while (NULL == (crlocn = strchr(rdpoint, 'n'))) {
/* set up cursize, rdpoint and rdsize, expand buffer */ rdsize = DELTASIZE + 1; /* allow for a final ' ' */ cursize += DELTASIZE;
/* -(EK)- No memory ? */ if (NULL == (temp = realloc(buffer, (size_t)cursize))) { /* ran out of memory */
/* Give at last the part read from the input */ *ln = buffer; /* partial line, next call may fail */ return NOMEM; }
est *la* maniere de faire une reallocation. En effet, si tu faisais directement
foo = realloc(foo, size);
en cas d'erreur, realloc te renvoie NULL et tu viens de perdre le pointeur sur l'espace originalement alloue a foo.
/* Read into the ' ' up */ rdpoint = buffer + (cursize - DELTASIZE - 1);
Voyons voir si je peux te faire un schema des choses. A regarder avec une police de largeur fixe. |<-----rdsizeÞLTASIZE+1-------->| <---------------------------cursize--------------------------------->| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ^ ^ | | buffer rdpoint
/*****?*****/
/* get the next piece of this line */ /* Note 1 */ if (NULL == fgets(rdpoint, rdsize, f)) { /* early EOF encountered */ crlocn = strchr(buffer, ' '); break; } } /* while line not complete */
*crlocn = ' '; /* mark line end, strip n */
Cette ligne est executee dans deux cas: a) terminaison normale du while. Ca veut dire que un 'n' a ete trouve dans la ligne et que crlocn pointe vers lui. Dans ce cas, la ligne ci-dessus efface le 'n', qui, a cause de la semantique de fgets est necessairement le dernier caractere de la ligne. b) terminaison anormale du while, qui n'arrive que dans le bloc ci-dessus, auquel cas crlocn pointe vers le ' ' final de la ligne, et ca ne peut pas faire de mal de le remplacer par un autre ' '.
Ca couvre tous les cas de figure de facon elegante, AMHA.
/* Fin Note 1 */
rdsize = crlocn - buffer; /* Note 2 */ if (NULL == (temp = realloc(buffer, (size_t)rdsize + 1))) { *ln = buffer; /* without reducing it */ return OK; } *ln = temp; /* Fin Note 2 */
A propos de note, note que c'est a priori une reallocation en diminution, de facon a n'avoir alloue que la taille exactement necessaire pour tenir la ligne complete.
return OK; } /* fggets */ /* End of ggets.c */
|-------------------------------------------|
Note 1 : On réalloue deux fois crlocn. Pourquoi pas faire directement *crlocn > ' ' ?
Ma reponse est ci-dessus.
Note 2 : Est ce plus avantageux de faire ça au lieu de :
if ( expression ) a = b; else a = c;
return OK;
? Pas forcement. C'est le style de l'auteur, et c'est son droit...
-- Bertrand Mollinier Toublet "In regard to Ducatis vs. women, it has been said: 'One is a sexy thing that you've just got to ride, even if it breaks down a lot, costs a lot of money, and will probably try to kill you'. However, nowadays I can't seem to remember which one is which." -- Peer Landa
Eddahbi Karim
[snip]
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Merci beaucoup, Voila ;), ThE_TemPLaR
[snip]
Ok merci pour les renseignements :-).
Je vais désormais voir si je peux pas modifier cette fonction de façon à
intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est
trop grand ou non.
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Merci beaucoup, Voila ;), ThE_TemPLaR
Bertrand Mollinier Toublet
Eddahbi Karim wrote:
[snip]
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Mais non !! C'est tout l'interet de la fonction ! C'est qu'il n'y a pas
de limite ! Tu prends une ligne entiere (ou tu te retrouves a cours de memoire, ce qui n'empeche pas, a priori, a la fonction de finir gracieusement), et c'est seulement ensuite que tu en fais ce que tu veux. Ca t'evite les inputs tronques parce que tu ne prends que 200 caracteres et que les 195 premiers caracteres sont ignorables (p.ex. des espaces...)
-- Bertrand Mollinier Toublet "Bikes are like ladies, if you don't take care of them all the time, when you feel like going back to them, it takes a lot of work" -- Riccardo Turchetto
Eddahbi Karim wrote:
[snip]
Ok merci pour les renseignements :-).
Je vais désormais voir si je peux pas modifier cette fonction de façon à
intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est
trop grand ou non.
Mais non !! C'est tout l'interet de la fonction ! C'est qu'il n'y a pas
de limite ! Tu prends une ligne entiere (ou tu te retrouves a cours de
memoire, ce qui n'empeche pas, a priori, a la fonction de finir
gracieusement), et c'est seulement ensuite que tu en fais ce que tu
veux. Ca t'evite les inputs tronques parce que tu ne prends que 200
caracteres et que les 195 premiers caracteres sont ignorables (p.ex. des
espaces...)
--
Bertrand Mollinier Toublet
"Bikes are like ladies, if you don't take care of them all the time,
when you feel like going back to them, it takes a lot of work"
-- Riccardo Turchetto
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Mais non !! C'est tout l'interet de la fonction ! C'est qu'il n'y a pas
de limite ! Tu prends une ligne entiere (ou tu te retrouves a cours de memoire, ce qui n'empeche pas, a priori, a la fonction de finir gracieusement), et c'est seulement ensuite que tu en fais ce que tu veux. Ca t'evite les inputs tronques parce que tu ne prends que 200 caracteres et que les 195 premiers caracteres sont ignorables (p.ex. des espaces...)
-- Bertrand Mollinier Toublet "Bikes are like ladies, if you don't take care of them all the time, when you feel like going back to them, it takes a lot of work" -- Riccardo Turchetto
Emmanuel Delahaye
In 'fr.comp.lang.c', Eddahbi Karim wrote:
[snip]
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Argh! Cette fonction est justement destinée à éviter ça.
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html <blank line> FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
In 'fr.comp.lang.c', Eddahbi Karim
<non.tu.ne.me.connais.pas.spavrai@Ifrance.paspam.com> wrote:
[snip]
Ok merci pour les renseignements :-).
Je vais désormais voir si je peux pas modifier cette fonction de façon à
intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est
trop grand ou non.
Argh! Cette fonction est justement destinée à éviter ça.
--
-ed- emdelYOURBRA@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Ok merci pour les renseignements :-). Je vais désormais voir si je peux pas modifier cette fonction de façon à intégrer une limite, je veux pouvoir savoir si ce que l'utilisateur est trop grand ou non.
Argh! Cette fonction est justement destinée à éviter ça.
-- -ed- [remove YOURBRA before answering me] The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html <blank line> FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/