#1101 Le 25/10/2011, à 01:56
- Pylades
Re : /* Topic des codeurs [6] */
Donc en effet tant que j'entre bien des entiers ça marche gentilement :
biaise@Tonton:~/Documents/programmes/Exos du tdcct$ ./exo1 Entrez un nombre entier : 543 Entrez un autre nombre entier : 44 Le produit de ces deux nombres entiers est : 23892
Mais si j'essaie de mettre un float
biaise@Tonton:~/Documents/programmes/Exos du tdcct$ ./exo1 Entrez un nombre entier : 2.5 Entrez un autre nombre entier : Le produit de ces deux nombres entiers est : 10 biaise@Tonton:~/Documents/programmes/Exos du tdcct$
Voilà, il m'a fait 2 * 5 quoi. mais… comment /D Je m'attendais à ce qu'il prenne pas en compte ce qu'il y a après le point car le int, il sait pas ce que c'est qu'un point normalement…
Bon là je réfléchouille à comment faire pour qu'à la fin, il me propose soit de quitter, soit de faire une nouvelle multiplication.
Voilà à quoi ça mène d’utiliser des fonctions dont on ne comprend pas le fonctionnement et sans traiter les erreurs sur de l’entrée d’utilisateur… Sur de l’entrée d’utilisateur, faut pas prendre de risques et préférer fgets à scanf.
Mais sinon, je crois bien que Rolinh voulait te faire manipuler les arguments passer au programme et utiliser la fonction strtol…
“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
Linus Torvalds – 12 janvier 2003
Hors ligne
#1102 Le 25/10/2011, à 02:49
- Вiɑise
Re : /* Topic des codeurs [6] */
Yep, le problème reste que les fonctions dont vous parlez, jles connais pas… Donc on verra dans quelques pages quand j'y serai.
'ne nuit vous tous.
Hors ligne
#1103 Le 25/10/2011, à 07:50
- grim7reaper
Re : /* Topic des codeurs [6] */
Hello World!
Bon, matinée du genre chargée (trucs administratifs tousssa…), j’essaye de passer donner des explications dès que possible (vraisemblablement pas avant le début de l’aprem).
Hors ligne
#1104 Le 25/10/2011, à 07:56
- The Uploader
Re : /* Topic des codeurs [6] */
@Biaise : Tu as vu l'arithmétique des pointeurs, ainsi que leur utilisation ?
- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10
Hors ligne
#1105 Le 25/10/2011, à 08:13
- HP
Re : /* Topic des codeurs [6] */
grim' a écrit :C’est le genre de truc qui, pour moi, faire la différence entre un bon programmeur et les pisseurs de code
Tout à fait. Dans le même genre, on peut tout à fait coder des getters/setters en Ruby, plutôt que d'utiliser attr_reader/attr_accessor, mais plus d'un Rubyist s'enfuira à la vue d'un code pareil.
En effet… merci !
cat /dev/urandom >/dev/null 2>&1 #github
Hors ligne
#1106 Le 25/10/2011, à 09:20
- Вiɑise
Re : /* Topic des codeurs [6] */
J'ai encore rien vu sur les pointeurs en fait. Pour l'instant j'en suis à jouer avec les do while, les for, les switch, en tâchant que ça compile du premier coup. Pour que ça fonctionne comme je m'y attendais du premier coup en revanche c'est pas encore ça
Hors ligne
#1107 Le 25/10/2011, à 09:36
- sweetly
Re : /* Topic des codeurs [6] */
Le plus important, surtout en commençant la prog par le C si on veut avoir un avenir avec ce langage (et avec la programmation tout court, d'ailleurs), c'est pas que ça marche, c'est de comprendre pourquoi ça marche ou pas (et quand a marche, vérifier que ça marche VRAIMENT).
Par exemple, quand tu codes un truc qui réponds correctement à la question de l'exercice (souvent loin d'une spécif détaillée), savoir expliquer ce qu'il se passe ou devrait se passer dans elle ou telle configuration, et le mieux, sans avoir à faire tourner ton code. Cette démarche oblige à bien connaître les fonctions que tu emploies, et ça, c'est vraiment pas du luxe.
Bon courage !
Hors ligne
#1108 Le 25/10/2011, à 09:59
- grim7reaper
Re : /* Topic des codeurs [6] */
Bon, finalement ce fut plus rapide que prévu (mais je suis pas encore sorti du sable…)
Voilà, il m'a fait 2 * 5 quoi. mais… comment /D Je m'attendais à ce qu'il prenne pas en compte ce qu'il y a après le point car le int, il sait pas ce que c'est qu'un point normalement…
C’est encore la faute du chat buffer.
L’utilisateur tape '2.5' + entrée, donc le buffer contient : '2', '.', '5', '\n'.
Le premier scanf lit un entier (%d), donc :
- il lit '2' => OK, on avance.
- il lit '.' => pas OK, ça fait pas partie d’un nombre entier => il s’arrête, remet '.' dans le buffer et renvoie 2 donc a = 2
Le buffer contient donc '.', '5' et '\n'.
Tu fais un getchar, il lit le caractère suivant dans le buffer => '.' est consommé.
Le buffer contient donc '5' et '\n'.
Le second scanf lit un entier (%d), donc :
- il lit '5' => OK, on avance.
- il lit '\n' => pas OK, ça fait pas partie d’un nombre entier => il s’arrête, remet '\n' dans le buffer et renvoie 5 donc b = 5
Le buffer contient donc '\n'.
Tu fais un getchar, il lit le caractère suivant dans le buffer => '\n' est consommé.
Le buffer est maintenant vide.
Tu as donc lu 2 et 5, il te renvoie 10. À aucun moment il ne te demande ton intervention car il a ce dont il a besoin dans le buffer.
Bon, je vais maintenant essayer d’expliquer les histoires d’argc et argv (je ne sais pas si j’aurais plus de succès qu’ArkSeth ^^).
Comme on te l’a dit récemment, il y a deux prototypes standard pour la fonction main :
- int main(void) si tu ne prends aucun paramètre du « monde extérieur » ;
- int main(int argc, char* argv[]) si tu prends en compte des paramètres.
Déjà, c’est quoi ces paramètres du « monde extérieur » ? Je suppose que tu as déjà vu des trucs comme ça :
ls -l
mkdir foobar
cd foobar
mv foobar qux
Et bien, ces programmes (ls, mkdir, cd et mv) reçoivent des paramètres (ce qui suit leurs noms).
Prenons
mv foobar qux
comme exemple.
Ici, « mv » c’est le nom du programme et « foobar » et « qux » sont deux arguments qu’on lui passe.
Au niveau langage C, comment ça se passe pour les récupérer ?
Déjà, il faut donner le bon prototype à main :
int main(int argc, char* argv[])
On va décortiquer ça. Il y a deux arguments :
- argc (pour ARGument Count) contient le nombre d’argument passés (sachant que le nom du programme lui-même est comptabilisé). Donc dans notre exemple il vaut 3 car « mv », « foobar » et « qux » ;
- argv (pour ARGument Value) contient les valeurs des arguments (toujours avec le nom du programme). C’est donc un tableau (car []) de chaîne de caractères (char*).
Dans notre exemple, le tableau à cette tête-là :
argv[0] = "mv"
argv[1] = "foobar"
argv[2] = "qux"
argv[0] contient TOUJOURS le nom de ton programme (donc argc vaudra toujours au minimum 1), les autres cases contiennent tes arguments.
Donc si on prend l’exemple de Rolinh :
./main 15 23
On a :
argv[0] = "./main"
argv[1] = "15"
argv[2] = "23"
Il te suffit donc de convertir argv[1] en nombre pour le mettre dans ta variable a et de convertir argv[2] en nombre pour le mettre dans ta variable b.
Puis tu fais ta multiplication.
Pour la conversion d’une chaîne de caractères en entier, il est conseillé d’utiliser strtol (atoi est déprécié, il ne gère pas les erreurs).
Mais de toutes façons si tu n’as pas vu la fonction strtol, l’exercice de Rolinh risque d’être un peu compliqué.
Sinon, dans le genre exercice pour débuter, ce TP du SdZ me semble pas trop mal.
Hors ligne
#1109 Le 25/10/2011, à 10:03
- Вiɑise
Re : /* Topic des codeurs [6] */
Beh oui c'est bien ce que je disais, trop de fonctions que je ne connais pas, je referai l'exo quand je saurais faire saisir des paramètres autrement qu'avec scanf.
Merci pour les explications sur ce type de main, c'était très clair.
Hors ligne
#1110 Le 25/10/2011, à 10:16
- Elzen
Re : /* Topic des codeurs [6] */
Ouaip, j'avoue qu'à côté des explications de grim7reaper, les miennes ont juste un zéro pointé ^^"
Note pour plus tard : ne pas essayer d'expliquer un truc en C en faisant autre chose et en étant pressé, ça demande qu'on prenne le temps.
Elzen : polisson, polémiste, polymathe ! (ex-ArkSeth)
Un script pour améliorer quelques trucs du forum.
La joie de t'avoir connu surpasse la peine de t'avoir perdu…
timezone[blocklist]
Hors ligne
#1111 Le 25/10/2011, à 10:19
- Вiɑise
Re : /* Topic des codeurs [6] */
En fait c'est la pédagogie, qu'il faut apprendre. Samuncle sait super bien faire. Tu devrais lui demander sa recette magique. /D
Hors ligne
#1112 Le 25/10/2011, à 10:26
- Elzen
Re : /* Topic des codeurs [6] */
Bah la pédagogie en général, j'ai pas trop de soucis non plus, quand même, ça a été mon boulot Demande moi de t'expliquer autre chose, y a pas de soucis ^^
Mais j'pense plutôt que c'est surtout que le C, j'suis pas encore super à l'aise avec, donc par peur de dire des bêtises, j'n'ose pas aborder l'explication correctement.
Et comme j'n'avais pas le temps de faire les vérifs requises pour être sûr de moi, bah, j'ai loupé mon coup.
Dernière modification par ArkSeth (Le 25/10/2011, à 10:27)
Elzen : polisson, polémiste, polymathe ! (ex-ArkSeth)
Un script pour améliorer quelques trucs du forum.
La joie de t'avoir connu surpasse la peine de t'avoir perdu…
timezone[blocklist]
Hors ligne
#1113 Le 25/10/2011, à 10:51
- Rolinh
Re : /* Topic des codeurs [6] */
J'avais été fouiller dans mes vieux TPs et avais pris le premier exercice de mon premier TP de C et l'avais un peu simplifié donc pardonne-moi, je ne pensais pas que c'était trop compliqué.
Ceci dit, je vais essayer de détailler un peu plus l'histoire du buffer et de getchar puisque le problème rencontré la première fois est revenu.
Si tu demandes à ton utilisateur de rentrer un caractère ('s' par exemple), et que ton utilisateur rentre une chaîne de caractères, mettons "Vive Ubuntu" et presse enter, dans le buffer tu as ceci "Vive Ubuntu\n".
Si tu utilises getchar pour récupérer le caractère que tu voulais, tu récupéreras 'V' et dans le buffer il restera "ive Ubuntu\n".
Par conséquent, on voit bien que le buffer n'est pas vide. Donc si le coup d'après tu lui demandes un autre caractère sans avoir vidé le buffer et qu'il rentre 'C', en utilisant un getchar, tu récupéreras 'i' et... ben tiens, dis moi ce qu'il reste dans le buffer?
Hors ligne
#1114 Le 25/10/2011, à 10:54
- Вiɑise
Re : /* Topic des codeurs [6] */
ve Ubuntu\n (ça en fait du monde)
Bon j'ai compris, désormais je tirerai toujours la chasse entre un scanf et un getchar () ^^
Et pour la complexité de l'exo : je crois que c'est simplement qu'on a pas appris les choses dans le même ordre.
Dernière modification par Вiɑise (Le 25/10/2011, à 10:55)
Hors ligne
#1115 Le 25/10/2011, à 11:07
- grim7reaper
Re : /* Topic des codeurs [6] */
Par conséquent, on voit bien que le buffer n'est pas vide. Donc si le coup d'après tu lui demandes un autre caractère sans avoir vidé le buffer et qu'il rentre 'C', en utilisant un getchar, tu récupéreras 'i' et... ben tiens, dis moi ce qu'il reste dans le buffer?
Hum hum, je vais faire mon chieur mais le gus pourra pas rentrer 'C'. Vu que le buffer n’est pas vide, on ne va pas lui demander son avis
Bon j'ai compris, désormais je tirerai toujours la chasse entre un scanf et un getchar () ^^
C’est l’idée, d’ailleurs il y a une fonction qui a un nom tout à fait adapté : fflush.
Le souci c’est qu’il ne faut pas l’utiliser sur les flux en lecture (donc stdin, celui que lisent scanf et getchar), donc faut passer par des fonctions comme Rolinh et moi on a posté.
D’ailleurs, je ne serais pas surpris que ton prof soit du genre à faire des :
fflush(stdin);
Et pour la complexité de l'exo : je crois que c'est simplement qu'on a pas appris les choses dans le même ordre.
T’as regardé celui que j’ai mis en lien ?
Je pense pas qu’il fasse appel à des notions que tu n’as pas (sauf le tirage de nombres pseudo-aléatoire, mais ça c’est expliqué dans l’énoncé).
Hors ligne
#1116 Le 25/10/2011, à 11:16
- Rolinh
Re : /* Topic des codeurs [6] */
Rolinh a écrit :Par conséquent, on voit bien que le buffer n'est pas vide. Donc si le coup d'après tu lui demandes un autre caractère sans avoir vidé le buffer et qu'il rentre 'C', en utilisant un getchar, tu récupéreras 'i' et... ben tiens, dis moi ce qu'il reste dans le buffer?
Hum hum, je vais faire mon chieur mais le gus pourra pas rentrer 'C'. Vu que le buffer n’est pas vide, on ne va pas lui demander son avis
cépafo Je n'y avais même plus pensé. ^^
@Вiɑise: ce n'était pas un cours de C ou même de programmation. On devait se débrouiller pour trouver les infos.
Hors ligne
#1117 Le 25/10/2011, à 11:18
- Вiɑise
Re : /* Topic des codeurs [6] */
Pas encore regardé car j'ai une matière qui me passionne moins à réviser alors vaut mieux pas que je commence ça maintenant Demain vacances, ça va coder sévère !
OMG la fonction s'appelle vraiment "flush"… Programmeurs je vous aime
Hors ligne
#1118 Le 25/10/2011, à 11:25
- The Uploader
Re : /* Topic des codeurs [6] */
OMG la fonction s'appelle vraiment "flush"…
Programmeurs je vous aime
Pour bien t'en rappeler : http://www.youtube.com/watch?v=BYW6C44zo24
- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10
Hors ligne
#1119 Le 25/10/2011, à 11:59
- Rolinh
Re : /* Topic des codeurs [6] */
A toute fin utile, je te fournis un corrigé de mon petit exercice:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int
main(int argc, char *argv[])
{
long n1, n2;
if (argc > 3) {
(void)fputs("ERROR: too many arguments\n", stderr);
return EXIT_FAILURE;
/* NOTREACHED */
} else if (argc < 3) {
(void)fputs("ERROR: missing argument(s)\n", stderr);
return EXIT_FAILURE;
/* NOTREACHED */
}
n1 = strtol(argv[1], (char **) NULL, 10);
if (n1 == LONG_MIN || n1 == LONG_MAX) {
(void)perror("Error on number");
return EXIT_FAILURE;
/* NOTREACHED */
}
n2 = strtol(argv[2], (char **) NULL, 10);
if (n2 == LONG_MIN || n2 == LONG_MAX) {
(void)perror("Error on number");
return EXIT_FAILURE;
/* NOTREACHED */
}
(void)printf("%ld X %ld = %ld\n", n1, n2, n1 * n2);
return EXIT_SUCCESS;
/* NOTREACHED */
}
Hors ligne
#1120 Le 25/10/2011, à 12:01
- Вiɑise
Re : /* Topic des codeurs [6] */
Hahaha c'est bourré de mots que j'ai jamais vus.
Merci rolinh jme garde ça de côté
Hors ligne
#1121 Le 25/10/2011, à 12:10
- grim7reaper
Re : /* Topic des codeurs [6] */
A toute fin utile, je te fournis un corrigé de mon petit exercice:
La gestion des erreurs est bancale, c’est normal car c’est un corrigé d’exercice ou il faut que je détaille ?
Hahaha c'est bourré de mots que j'ai jamais vus.
Non et puis Rolinh il a un style un peu particulier (genre les (void), les /* NOTREACHED */, etc.), c’est du style BSD.
Ça peut perturber au début (mais moins que du style GNU )
Dernière modification par grim7reaper (Le 25/10/2011, à 12:17)
Hors ligne
#1122 Le 25/10/2011, à 12:11
- Вiɑise
Re : /* Topic des codeurs [6] */
En fait vous êtes des artistes ^^
Hors ligne
#1123 Le 25/10/2011, à 12:25
- Ras'
Re : /* Topic des codeurs [6] */
Hej les pros du CSS/html/prout, y'a moyen d'avoir des fonts comme quand on met du texte en small capitals en Latex ? (c'est à dire que les Majuscules restent plus grandes que les lettres normales, bien que ça soit des lettres capitales)
Va t'faire shampouiner par le compteur_V2 en timezone[Canada/Eastern] !
Les types awesome n'ont rien à prouver. À personne.
'k bye là
Hors ligne
#1124 Le 25/10/2011, à 12:44
- Rolinh
Re : /* Topic des codeurs [6] */
La gestion des erreurs est bancale, c’est normal car c’est un corrigé d’exercice ou il faut que je détaille ?
C'est normal. Je ne voulais pas alourdir plus que nécessaire et puis j'avais fait exprès de dire que l'on donnait 2 entiers en entrées afin de simplifier.
Et voui, il faut pardonner mon style ou s'y faire
Hors ligne
#1125 Le 25/10/2011, à 12:49
- grim7reaper
Re : /* Topic des codeurs [6] */
Si t’es sûr qu’on te donne deux entiers, tu peux effectivement omettre certaines vérif’. Je comprends que tu simplifies.
Cela dit, même avec cette hypothèse (on te passe deux entiers) et ton code bah on a un comportement assez perturbant du genre :
Error on number: Success
Avec ce code :
n1 = strtol(argv[1], (char **) NULL, 10);
if (n1 == LONG_MIN || n1 == LONG_MAX) {
(void)perror("Error on number");
return EXIT_FAILURE;
/* NOTREACHED */
}
Tu as des faux positifs si l’utilisateur passe LONG_MIN ou LONG_MAX en paramètre.
Bah oui, LONG_MIN et LONG_MAX sont des valeurs légitimes. Pour être sûr que c’est une erreur faut aussi lire errno (et donc le positionner à 0 avant l’appel) et tester s’il vaut ERANGE.
errno = 0;
n1 = strtol(argv[1], (char **) NULL, 10);
if (errno == ERANGE && (n1 == LONG_MIN || n1 == LONG_MAX)) {
(void)perror("Error on number");
return EXIT_FAILURE;
/* NOTREACHED */
}
(idem pour la conversion de n2)
En fait, il suffisait de lire le man
Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN (LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call.
Dernière modification par grim7reaper (Le 25/10/2011, à 12:58)
Hors ligne