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.");
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il
s'agit d'une question de clarte et d'homogeneite du code. Un code
aeroport, c'est trois lettres. Pas trois lettres et un retour chariot.
Que ta fonction d'input te le file avec un retour chariot ne doit pas
avoir d'incidence sur ce que tu stockes.
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Il vaut mieux que la fonction de saisie se débarrasse des 'n'.
Bertrand Mollinier Toublet
Laurent Wacrenier wrote:
Bertrand Mollinier Toublet écrit:
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Il vaut mieux que la fonction de saisie se débarrasse des 'n'.
Mais nous sommes bien d'accord. Et c'est ce que je dis, non ? Peut-etre
que ce que tu as rate, c'est que quand je dis trois lettres, etant donne que c'est une chaine de caracteres, c'est bien entendu trois lettres et le 0 final...
-- 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
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il
s'agit d'une question de clarte et d'homogeneite du code. Un code
aeroport, c'est trois lettres. Pas trois lettres et un retour chariot.
Que ta fonction d'input te le file avec un retour chariot ne doit pas
avoir d'incidence sur ce que tu stockes.
Il vaut mieux que la fonction de saisie se débarrasse des 'n'.
Mais nous sommes bien d'accord. Et c'est ce que je dis, non ? Peut-etre
que ce que tu as rate, c'est que quand je dis trois lettres, etant donne
que c'est une chaine de caracteres, c'est bien entendu trois lettres et
le 0 final...
--
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
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Il vaut mieux que la fonction de saisie se débarrasse des 'n'.
Mais nous sommes bien d'accord. Et c'est ce que je dis, non ? Peut-etre
que ce que tu as rate, c'est que quand je dis trois lettres, etant donne que c'est une chaine de caracteres, c'est bien entendu trois lettres et le 0 final...
-- 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
Laurent Wacrenier
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.
C'est bien entendu une question de point de vue, mais il me semble que
cette expression est suffisament idiomatique et concise pour etre utilisee telle quelle dans ton code. En particulier, ca evite les problemes eventuels de double evaluation de ton argument...
Ok
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Je vais enlever les 'n' avec getstring :-)
Je suis surpris que personne n'ait fait de remarque a propos de cette fonction. Tu prends une chaine de caracteres, string, et tu la modifies probablement (dans le cas ou p est non nul). Dans ces conditions, c'est conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un cote tu modifie ton argument (a priori declare non modifiable), de l'autre, tu fais une operation completement sans rapport (vider stdin).
[snip]
Me suis gourré effectivement c'est ( char *const string ) et non ( char const *string )
Sinon j'ai pris le reste de la fonction sur la FAQ.
Je vais tenter ggets()
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}};
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Je ne savais pas que ça faisait la même chose, ma logique était d'initialiser tout les éléments...
/* Display the airport codes */ aircodes();
/* Get the client flight informations */ (void) puts("Welcome.");
C'est bien entendu une question de point de vue, mais il me semble que
cette expression est suffisament idiomatique et concise pour etre
utilisee telle quelle dans ton code. En particulier, ca evite les
problemes eventuels de double evaluation de ton argument...
Ok
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il
s'agit d'une question de clarte et d'homogeneite du code. Un code
aeroport, c'est trois lettres. Pas trois lettres et un retour chariot.
Que ta fonction d'input te le file avec un retour chariot ne doit pas
avoir d'incidence sur ce que tu stockes.
Je vais enlever les 'n' avec getstring :-)
Je suis surpris que personne n'ait fait de remarque a propos de cette
fonction. Tu prends une chaine de caracteres, string, et tu la modifies
probablement (dans le cas ou p est non nul). Dans ces conditions, c'est
conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton
parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un
cote tu modifie ton argument (a priori declare non modifiable), de
l'autre, tu fais une operation completement sans rapport (vider stdin).
[snip]
Me suis gourré effectivement c'est ( char *const string ) et non ( char
const *string )
Sinon j'ai pris le reste de la fonction sur la FAQ.
Je vais tenter ggets()
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}};
Qu'est ce qui ne va pas avec:
reservation client_fl = {0};
?
Je ne savais pas que ça faisait la même chose, ma logique était
d'initialiser tout les éléments...
/* Display the airport codes */
aircodes();
/* Get the client flight informations */ (void) puts("Welcome.");
C'est bien entendu une question de point de vue, mais il me semble que
cette expression est suffisament idiomatique et concise pour etre utilisee telle quelle dans ton code. En particulier, ca evite les problemes eventuels de double evaluation de ton argument...
Ok
Pour repondre ici a ta question sur pourquoi ne pas stocker les 'n': il s'agit d'une question de clarte et d'homogeneite du code. Un code aeroport, c'est trois lettres. Pas trois lettres et un retour chariot. Que ta fonction d'input te le file avec un retour chariot ne doit pas avoir d'incidence sur ce que tu stockes.
Je vais enlever les 'n' avec getstring :-)
Je suis surpris que personne n'ait fait de remarque a propos de cette fonction. Tu prends une chaine de caracteres, string, et tu la modifies probablement (dans le cas ou p est non nul). Dans ces conditions, c'est conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un cote tu modifie ton argument (a priori declare non modifiable), de l'autre, tu fais une operation completement sans rapport (vider stdin).
[snip]
Me suis gourré effectivement c'est ( char *const string ) et non ( char const *string )
Sinon j'ai pris le reste de la fonction sur la FAQ.
Je vais tenter ggets()
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}};
Qu'est ce qui ne va pas avec: reservation client_fl = {0}; ?
Je ne savais pas que ça faisait la même chose, ma logique était d'initialiser tout les éléments...
/* Display the airport codes */ aircodes();
/* Get the client flight informations */ (void) puts("Welcome.");
err = ask( &client_fl );
return err; }
Merci beaucoup :), Voila, ThE_TemPLaR
Eddahbi Karim
Eddahbi Karim écrit:
Il y a un caractère de trop à chaque fois. On peut aussi écrire : char flight_nb[sizeof("1234")]; char orig_air_code[sizeof("ABC")]; char dest_air_code[sizeof("ABC")]; char start_time[sizeof("12:34")]; char end_time[sizeof("12:34")];
Ça évite de faire le calcul.
Ok :)
/* If nothing is wrong, grab the user value */ if ( err = >> EXIT_SUCCESS )
Les commentaires avant le code, c'est pas très lisible.
C'est le client de news qui à fait ça quand j'ai voulu faire une recoupe automatique , normalement je mets toujours le code en dessous du commentaire.
Il y a un caractère de trop à chaque fois. On peut aussi écrire :
char flight_nb[sizeof("1234")];
char orig_air_code[sizeof("ABC")];
char dest_air_code[sizeof("ABC")];
char start_time[sizeof("12:34")];
char end_time[sizeof("12:34")];
Ça évite de faire le calcul.
Ok :)
/* If nothing is wrong, grab the user value */ if ( err = >> EXIT_SUCCESS )
Les commentaires avant le code, c'est pas très lisible.
C'est le client de news qui à fait ça quand j'ai voulu faire une recoupe
automatique , normalement je mets toujours le code en dessous du
commentaire.
Il y a un caractère de trop à chaque fois. On peut aussi écrire : char flight_nb[sizeof("1234")]; char orig_air_code[sizeof("ABC")]; char dest_air_code[sizeof("ABC")]; char start_time[sizeof("12:34")]; char end_time[sizeof("12:34")];
Ça évite de faire le calcul.
Ok :)
/* If nothing is wrong, grab the user value */ if ( err = >> EXIT_SUCCESS )
Les commentaires avant le code, c'est pas très lisible.
C'est le client de news qui à fait ça quand j'ai voulu faire une recoupe automatique , normalement je mets toujours le code en dessous du commentaire.
Merci, Voila :), ThE_TemPLaR
Eddahbi Karim
[...]
Pour avoir les coordonnées d'une ville dans le monde :
http://www.heavens-above.com/countries.asp
Pas mal cet exercice :). Je vais voir si je peux inclure ce système de calcul de distance dans mon programme :).
Voila, ThE_TemPLaR
[...]
Pour avoir les coordonnées d'une ville dans le monde :
http://www.heavens-above.com/countries.asp
Pas mal cet exercice :).
Je vais voir si je peux inclure ce système de calcul de distance dans mon
programme :).
Pour avoir les coordonnées d'une ville dans le monde :
http://www.heavens-above.com/countries.asp
Pas mal cet exercice :). Je vais voir si je peux inclure ce système de calcul de distance dans mon programme :).
Voila, ThE_TemPLaR
Eddahbi Karim
/* -ed- : Probablement tres faux. * La taille qui nous interesse * est celle du tableau de reference. * 'string' est un pointeur */ for (number = 0 ; number < FIRST_DIM_SIZE (string) + 1 && err != EXIT_SUCCESS ; number++) #else for (number = 0 ; number < FIRST_DIM_SIZE (codes) && err != EXIT_SUCCESS ; number++)
Effectivement, c'est bien codes et non string.
Sinon t'as rien dit sur les 'n' toi :D.
Merci pour les renseignements, Voila ;), ThE_TemPLaR
/* -ed- : Probablement tres faux.
* La taille qui nous interesse
* est celle du tableau de reference.
* 'string' est un pointeur
*/
for (number = 0
; number < FIRST_DIM_SIZE (string) + 1
&& err != EXIT_SUCCESS
; number++)
#else
for (number = 0
; number < FIRST_DIM_SIZE (codes)
&& err != EXIT_SUCCESS
; number++)
Effectivement, c'est bien codes et non string.
Sinon t'as rien dit sur les 'n' toi :D.
Merci pour les renseignements,
Voila ;),
ThE_TemPLaR
/* -ed- : Probablement tres faux. * La taille qui nous interesse * est celle du tableau de reference. * 'string' est un pointeur */ for (number = 0 ; number < FIRST_DIM_SIZE (string) + 1 && err != EXIT_SUCCESS ; number++) #else for (number = 0 ; number < FIRST_DIM_SIZE (codes) && err != EXIT_SUCCESS ; number++)
Effectivement, c'est bien codes et non string.
Sinon t'as rien dit sur les 'n' toi :D.
Merci pour les renseignements, Voila ;), ThE_TemPLaR
Bertrand Mollinier Toublet
Eddahbi Karim wrote:
Je suis surpris que personne n'ait fait de remarque a propos de cette fonction. Tu prends une chaine de caracteres, string, et tu la modifies probablement (dans le cas ou p est non nul). Dans ces conditions, c'est conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un cote tu modifie ton argument (a priori declare non modifiable), de l'autre, tu fais une operation completement sans rapport (vider stdin).
Me suis gourré effectivement c'est ( char *const string ) et non ( char
const *string )
Bon. J'allais faire une remarque idiote, a propos de comment c'etait pas
tres utile d'avoir ce const, dans la mesure ou chez l'appelant, de toute facon, ca ne changeait rien, a cause de la semantique d'appel par valeur. Et puis j'ai reflechis a un probleme que je viens d'avoir, un truc du genre:
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) { ... }
Par contre, si tu commences a declarer certains de tes parametres de fonction comme etant const, autant le faire partout. Ou nulle part. Si tu le fais nulle part, ca ne change rien (du point de vue de l'appelant) pour tes variables non-pointeur et t'offre un peu, mais pas beaucoup de securite pour tes pointeurs (comme dans l'exemple ci-dessus. Note qu'avec dix minutes de reflexion en plus, je me suis rendu compte que mon code etait vraiment tordu et je l'ai remplace par quelque chose de mieux foutu). Si tu le fais partout, bon c'est plus lourd, mais ca permet peut-etre d'enforcer certaines regles de bonne conduite dans tes fonctions (p.ex. ne pas modifier un argument de la fonction, juste en utiliser la valeur).
Je vais tenter ggets()
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.
-- Bertrand Mollinier Toublet "Uno no se muere cuando debe, sino cuando puede" -- Cor. Aureliano Buendia
Eddahbi Karim wrote:
Je suis surpris que personne n'ait fait de remarque a propos de cette
fonction. Tu prends une chaine de caracteres, string, et tu la modifies
probablement (dans le cas ou p est non nul). Dans ces conditions, c'est
conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton
parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un
cote tu modifie ton argument (a priori declare non modifiable), de
l'autre, tu fais une operation completement sans rapport (vider stdin).
Me suis gourré effectivement c'est ( char *const string ) et non ( char
const *string )
Bon. J'allais faire une remarque idiote, a propos de comment c'etait pas
tres utile d'avoir ce const, dans la mesure ou chez l'appelant, de toute
facon, ca ne changeait rien, a cause de la semantique d'appel par valeur.
Et puis j'ai reflechis a un probleme que je viens d'avoir, un truc du genre:
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)
{
...
}
Par contre, si tu commences a declarer certains de tes parametres de
fonction comme etant const, autant le faire partout. Ou nulle part. Si
tu le fais nulle part, ca ne change rien (du point de vue de l'appelant)
pour tes variables non-pointeur et t'offre un peu, mais pas beaucoup de
securite pour tes pointeurs (comme dans l'exemple ci-dessus. Note
qu'avec dix minutes de reflexion en plus, je me suis rendu compte que
mon code etait vraiment tordu et je l'ai remplace par quelque chose de
mieux foutu).
Si tu le fais partout, bon c'est plus lourd, mais ca permet peut-etre
d'enforcer certaines regles de bonne conduite dans tes fonctions (p.ex.
ne pas modifier un argument de la fonction, juste en utiliser la
valeur).
Je vais tenter ggets()
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.
--
Bertrand Mollinier Toublet
"Uno no se muere cuando debe, sino cuando puede"
-- Cor. Aureliano Buendia
Je suis surpris que personne n'ait fait de remarque a propos de cette fonction. Tu prends une chaine de caracteres, string, et tu la modifies probablement (dans le cas ou p est non nul). Dans ces conditions, c'est conceptuellement maladroit (pour ne pas dire incorrect) d'indiquer ton parametre comme etant de type const char *.
En plus la fonction est plutot mal foutue, si tu veux mon avis. D'un cote tu modifie ton argument (a priori declare non modifiable), de l'autre, tu fais une operation completement sans rapport (vider stdin).
Me suis gourré effectivement c'est ( char *const string ) et non ( char
const *string )
Bon. J'allais faire une remarque idiote, a propos de comment c'etait pas
tres utile d'avoir ce const, dans la mesure ou chez l'appelant, de toute facon, ca ne changeait rien, a cause de la semantique d'appel par valeur. Et puis j'ai reflechis a un probleme que je viens d'avoir, un truc du genre:
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) { ... }
Par contre, si tu commences a declarer certains de tes parametres de fonction comme etant const, autant le faire partout. Ou nulle part. Si tu le fais nulle part, ca ne change rien (du point de vue de l'appelant) pour tes variables non-pointeur et t'offre un peu, mais pas beaucoup de securite pour tes pointeurs (comme dans l'exemple ci-dessus. Note qu'avec dix minutes de reflexion en plus, je me suis rendu compte que mon code etait vraiment tordu et je l'ai remplace par quelque chose de mieux foutu). Si tu le fais partout, bon c'est plus lourd, mais ca permet peut-etre d'enforcer certaines regles de bonne conduite dans tes fonctions (p.ex. ne pas modifier un argument de la fonction, juste en utiliser la valeur).
Je vais tenter ggets()
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.
-- Bertrand Mollinier Toublet "Uno no se muere cuando debe, sino cuando puede" -- Cor. Aureliano Buendia
Emmanuel Delahaye
In 'fr.comp.lang.c', Eddahbi Karim wrote:
Sinon t'as rien dit sur les 'n' toi :D.
Bah, les autres ont bien parlé! Il faut les virer. Je pensais bêtement que ton wipestring() le faisait...
-- -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:
Sinon t'as rien dit sur les 'n' toi :D.
Bah, les autres ont bien parlé! Il faut les virer. Je pensais bêtement que
ton wipestring() le faisait...
--
-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/