Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;
}
#endif /* defined TEST */
Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;
}
#endif /* defined TEST */
Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;
}
#endif /* defined TEST */
char buff[BUFSIZ];
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
d'une part c'est BUFSIZ et non (BUFSIZ - 1) qui devrait être utilisé,
d'autre part tester le retour de fgets est suffisant et je pense que le
« && buff[0] » n'échouera jamais.
Si je ne me trompe pas,
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
char buff[BUFSIZ];
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
d'une part c'est BUFSIZ et non (BUFSIZ - 1) qui devrait être utilisé,
d'autre part tester le retour de fgets est suffisant et je pense que le
« && buff[0] » n'échouera jamais.
Si je ne me trompe pas,
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
char buff[BUFSIZ];
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
d'une part c'est BUFSIZ et non (BUFSIZ - 1) qui devrait être utilisé,
d'autre part tester le retour de fgets est suffisant et je pense que le
« && buff[0] » n'échouera jamais.
Si je ne me trompe pas,
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;}
#endif /* defined TEST */
Pourquoi ligne 14 l'auteur place-t-il un 0 en final ?
Et quand je
vois le peu de temps que les étudiants passent à bosser, je suis en f ait
pas très étonné qu'ils aient un niveau très médiocre en C.
Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;}
#endif /* defined TEST */
Pourquoi ligne 14 l'auteur place-t-il un 0 en final ?
Et quand je
vois le peu de temps que les étudiants passent à bosser, je suis en f ait
pas très étonné qu'ils aient un niveau très médiocre en C.
Au passage, je suis quand même allé regarder dans du code réel. Par
exemple dans les GNU core utilities, fichier getdate.c je trouve ceci :
/* ligne 0 */
#if TEST
#include <stdio.h>
int
main (int ac, char **av)
{
char buff[BUFSIZ];
time_t d;
printf ("Enter date, or blank line to exit.nt> ");
fflush (stdout);
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
d = get_date (buff, 0);
if (d == (time_t) -1)
printf ("Bad format - couldn't convert.n");
else
printf ("%s", ctime (&d));
printf ("t> ");
fflush (stdout);
}
return 0;}
#endif /* defined TEST */
Pourquoi ligne 14 l'auteur place-t-il un 0 en final ?
Et quand je
vois le peu de temps que les étudiants passent à bosser, je suis en f ait
pas très étonné qu'ils aient un niveau très médiocre en C.
In article <4af4a2cc$0$438$,
candide wrote:
Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les tab leaux,
et je leur dis systematiquement que, dans le doute, il faut verifier l'in dex
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues su r les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Dans un autre ordre d'idees, en programmation OO, je vois passer des tas
d'etudiants qui ont tres bien retenu toutes les subtilites de l'heritage
et qui savent quand les arguments seront co/contra-variants, mais qui deg ainent
l'heritage pour absolument tout, et me font des classes valises la ou la
composition est l'outil approprie. Ou bien qui ne connaissent pas des pat tern
aussi utiles que Template Method ou Compiler Firewall...
In article <4af4a2cc$0$438$426a3...@news.free.fr>,
candide <cand...@free.invalid> wrote:
Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les tab leaux,
et je leur dis systematiquement que, dans le doute, il faut verifier l'in dex
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues su r les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Dans un autre ordre d'idees, en programmation OO, je vois passer des tas
d'etudiants qui ont tres bien retenu toutes les subtilites de l'heritage
et qui savent quand les arguments seront co/contra-variants, mais qui deg ainent
l'heritage pour absolument tout, et me font des classes valises la ou la
composition est l'outil approprie. Ou bien qui ne connaissent pas des pat tern
aussi utiles que Template Method ou Compiler Firewall...
In article <4af4a2cc$0$438$,
candide wrote:
Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les tab leaux,
et je leur dis systematiquement que, dans le doute, il faut verifier l'in dex
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues su r les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Dans un autre ordre d'idees, en programmation OO, je vois passer des tas
d'etudiants qui ont tres bien retenu toutes les subtilites de l'heritage
et qui savent quand les arguments seront co/contra-variants, mais qui deg ainent
l'heritage pour absolument tout, et me font des classes valises la ou la
composition est l'outil approprie. Ou bien qui ne connaissent pas des pat tern
aussi utiles que Template Method ou Compiler Firewall...
On 7 nov, 08:53, (Marc Espie) wrote:In article <4af4a2cc$0$438$,
candide wrote:Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les
tableaux,et je leur dis systematiquement que, dans le doute, il faut verifier l'index
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues sur les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Ca fait presque 6 mois que j'apprends le C seul avec livres, tuto,
exercices et usenet... J'ai une formation initiale en comptabilité.
Je passe aussi beaucoup de temps sur les tableaux car pour un premier
langage de programmation je trouve la logique des tableaux assez
proche d'une gestion de données comme on trouve dans les bases de
données... Je sais SQL plus puissant mais c'est que pour les
requêtes...
Y a-t-il un intérêt à approfondir les tableaux en C dans mon cas?
J'essaye actuellement de bien comprendre les tableaux, les pointeurs
et l'arithmétique avant de continuer...
Merci
On 7 nov, 08:53, es...@lain.home (Marc Espie) wrote:
In article <4af4a2cc$0$438$426a3...@news.free.fr>,
candide <cand...@free.invalid> wrote:
Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les
tableaux,
et je leur dis systematiquement que, dans le doute, il faut verifier l'index
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues sur les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Ca fait presque 6 mois que j'apprends le C seul avec livres, tuto,
exercices et usenet... J'ai une formation initiale en comptabilité.
Je passe aussi beaucoup de temps sur les tableaux car pour un premier
langage de programmation je trouve la logique des tableaux assez
proche d'une gestion de données comme on trouve dans les bases de
données... Je sais SQL plus puissant mais c'est que pour les
requêtes...
Y a-t-il un intérêt à approfondir les tableaux en C dans mon cas?
J'essaye actuellement de bien comprendre les tableaux, les pointeurs
et l'arithmétique avant de continuer...
Merci
On 7 nov, 08:53, (Marc Espie) wrote:In article <4af4a2cc$0$438$,
candide wrote:Si tu veux d'autres exemples, je passe aussi pas mal de temps sur les
tableaux,et je leur dis systematiquement que, dans le doute, il faut verifier l'index
avant d'acceder a un element de tableau. Ou sinon, essayer de faire plus
simple dans le code. Je leur dis aussi qu'ils ne seront pas evalues sur les
astuces tordues qu'ils peuvent mettre dans leur code, bien au contraire. Que
c'est plus difficile de faire du code simple et clair.
Ca fait presque 6 mois que j'apprends le C seul avec livres, tuto,
exercices et usenet... J'ai une formation initiale en comptabilité.
Je passe aussi beaucoup de temps sur les tableaux car pour un premier
langage de programmation je trouve la logique des tableaux assez
proche d'une gestion de données comme on trouve dans les bases de
données... Je sais SQL plus puissant mais c'est que pour les
requêtes...
Y a-t-il un intérêt à approfondir les tableaux en C dans mon cas?
J'essaye actuellement de bien comprendre les tableaux, les pointeurs
et l'arithmétique avant de continuer...
Merci
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
Le problème c'est qu'ici :
char buff[BUFSIZ]; /* buff[0] vaut n'importe quoi */
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
Si on rentre une chaîne vide fgets va renvoyer NULL donc buff[0] ne sera
pas évalué.
De plus, si on imagine que fgets ne renverrai pas NULL (ce qui est faux)
et donc que buff[0] soit évalué, il vaudrait n'importe quoi sur le
premier appel et vaudrait toujours quelque chose sur les appels suivants
car il était déjà valide à l'appel précédent.
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
Le problème c'est qu'ici :
char buff[BUFSIZ]; /* buff[0] vaut n'importe quoi */
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
Si on rentre une chaîne vide fgets va renvoyer NULL donc buff[0] ne sera
pas évalué.
De plus, si on imagine que fgets ne renverrai pas NULL (ce qui est faux)
et donc que buff[0] soit évalué, il vaudrait n'importe quoi sur le
premier appel et vaudrait toujours quelque chose sur les appels suivants
car il était déjà valide à l'appel précédent.
while (fgets (buff, ...) && buff [0])
permet de tester si on a entré une chaine non vide
(dont le premier caractère est différent de ),
à peu près équivalent à écrire : && strlen (buff) > 0
Le problème c'est qu'ici :
char buff[BUFSIZ]; /* buff[0] vaut n'importe quoi */
buff[BUFSIZ - 1] = 0;
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
Si on rentre une chaîne vide fgets va renvoyer NULL donc buff[0] ne sera
pas évalué.
De plus, si on imagine que fgets ne renverrai pas NULL (ce qui est faux)
et donc que buff[0] soit évalué, il vaudrait n'importe quoi sur le
premier appel et vaudrait toujours quelque chose sur les appels suivants
car il était déjà valide à l'appel précédent.
Par curiosité, j'aimerai bien savoir comment on fait pour envoyer un
' ' lors d'une saisie (sous UNIX).
Ctrl-@
Dans tous les cas, avoir un ' ' en entrée sur un fichier texte est peu
vraisemblable.
Pas plus invraisemblable qu'un autre caractère. Les outils GNU
utilisent très souvent le NUL comme séparateur de nom de fichier. Voir
"find" par exemple.
Par curiosité, j'aimerai bien savoir comment on fait pour envoyer un
' ' lors d'une saisie (sous UNIX).
Ctrl-@
Dans tous les cas, avoir un ' ' en entrée sur un fichier texte est peu
vraisemblable.
Pas plus invraisemblable qu'un autre caractère. Les outils GNU
utilisent très souvent le NUL comme séparateur de nom de fichier. Voir
"find" par exemple.
Par curiosité, j'aimerai bien savoir comment on fait pour envoyer un
' ' lors d'une saisie (sous UNIX).
Ctrl-@
Dans tous les cas, avoir un ' ' en entrée sur un fichier texte est peu
vraisemblable.
Pas plus invraisemblable qu'un autre caractère. Les outils GNU
utilisent très souvent le NUL comme séparateur de nom de fichier. Voir
"find" par exemple.
On 6 nov, 23:25, candide wrote:Marc Boyer a écrit :
Ici et dans tes messages précédents, tu as parfaitement traduit les
réactions des étudiants (et encore d'étudiants qui réagissent !)
> Non, les codes de retour, c'était la partie "maintenant,
> on fait attention",
> et ça va aussi avec les retours de malloc, etc.
Absolument. Question de progressivité qui s'impose pour moi comme une
évidence.
Une fois de plus, le C n'est pas un langage pour débutants en
informatique... Trop de subtilités à gérer d'un coup...
Certains
verront alors le C comme un langage compliqué, oui, c'est possible,
car la complexité est 'cachée' dans les autres langages. Ici, on est
proche du fonctionnement réel, donc les choses sont un peu moins
'bisounours'... C'est le prix à payer pour avoir du code efficace.
Ceci-dit, les E/S en Java, c'est pas d'une simplicité biblique non
plus... Quand au Pasca standard, ça n'existe carrément pas !
Heureusement, il y a Turbo Pascal (ou freePascal).
On 6 nov, 23:25, candide <cand...@free.invalid> wrote:
Marc Boyer a écrit :
Ici et dans tes messages précédents, tu as parfaitement traduit les
réactions des étudiants (et encore d'étudiants qui réagissent !)
> Non, les codes de retour, c'était la partie "maintenant,
> on fait attention",
> et ça va aussi avec les retours de malloc, etc.
Absolument. Question de progressivité qui s'impose pour moi comme une
évidence.
Une fois de plus, le C n'est pas un langage pour débutants en
informatique... Trop de subtilités à gérer d'un coup...
Certains
verront alors le C comme un langage compliqué, oui, c'est possible,
car la complexité est 'cachée' dans les autres langages. Ici, on est
proche du fonctionnement réel, donc les choses sont un peu moins
'bisounours'... C'est le prix à payer pour avoir du code efficace.
Ceci-dit, les E/S en Java, c'est pas d'une simplicité biblique non
plus... Quand au Pasca standard, ça n'existe carrément pas !
Heureusement, il y a Turbo Pascal (ou freePascal).
On 6 nov, 23:25, candide wrote:Marc Boyer a écrit :
Ici et dans tes messages précédents, tu as parfaitement traduit les
réactions des étudiants (et encore d'étudiants qui réagissent !)
> Non, les codes de retour, c'était la partie "maintenant,
> on fait attention",
> et ça va aussi avec les retours de malloc, etc.
Absolument. Question de progressivité qui s'impose pour moi comme une
évidence.
Une fois de plus, le C n'est pas un langage pour débutants en
informatique... Trop de subtilités à gérer d'un coup...
Certains
verront alors le C comme un langage compliqué, oui, c'est possible,
car la complexité est 'cachée' dans les autres langages. Ici, on est
proche du fonctionnement réel, donc les choses sont un peu moins
'bisounours'... C'est le prix à payer pour avoir du code efficace.
Ceci-dit, les E/S en Java, c'est pas d'une simplicité biblique non
plus... Quand au Pasca standard, ça n'existe carrément pas !
Heureusement, il y a Turbo Pascal (ou freePascal).
Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
Le 06-11-2009, Marc Espie a écrit :Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Donc tu parles des flux, ce truc étrange où ce que tu lis
disparaît, et puis EOF, c'est un entier qu'on ne peut pas coder
sur un char, sauf que c'est -1 en pratique (il va vite y avoir
un étudiant qui va faire un printf("%d",EOF)), mais qu'en fait,
c'est en temps qu'unsigned char qu'il est pas représentable...Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
J'ai hésité un temps à fournir une mini-bibliothèque:
int NEWBY_readInt();
Le 06-11-2009, Marc Espie <espie@lain.home> a écrit :
Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Donc tu parles des flux, ce truc étrange où ce que tu lis
disparaît, et puis EOF, c'est un entier qu'on ne peut pas coder
sur un char, sauf que c'est -1 en pratique (il va vite y avoir
un étudiant qui va faire un printf("%d",EOF)), mais qu'en fait,
c'est en temps qu'unsigned char qu'il est pas représentable...
Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
J'ai hésité un temps à fournir une mini-bibliothèque:
int NEWBY_readInt();
Le 06-11-2009, Marc Espie a écrit :Pour scanf, c'est quand meme tres simple: ca renvoie le nombre de valeurs
converties avec succes, et autre chose en cas de pepin.
C'est pas dur de faire
r = scanf("%d", &d);
if (r != 1) {
fprintf(stderr, "Chef, on a un problemen");
abort();
}
Pour getc: expliquer getc avant de parler d'EOF, ca me parait aberrant.
Donc tu parles des flux, ce truc étrange où ce que tu lis
disparaît, et puis EOF, c'est un entier qu'on ne peut pas coder
sur un char, sauf que c'est -1 en pratique (il va vite y avoir
un étudiant qui va faire un printf("%d",EOF)), mais qu'en fait,
c'est en temps qu'unsigned char qu'il est pas représentable...Dans le pire des cas, je suis pret a leur donner un idiome qui marche,
a utiliser tel quel, quitte a expliquer certains details apres...
J'ai hésité un temps à fournir une mini-bibliothèque:
int NEWBY_readInt();