Tableau dynamique de caractères - C - Programmation
Marsh Posté le 22-11-2006 à 08:13:14
Tu cumules deux problèmes :
- L'utilisation de scanf qui est TRES difficile mais faisable.
- L'utilisation de gets qui est déconseillée puisque gets est un bug (pas de test sur la longueur de la chaine saisie), il faut utiliser fgets(tempo, sizeof tempo, stdin).
Ton problème vient du fait que scanf laisse dans le buffer de saisie le '\n', et donc que la première chose lue par le gets est ce '\n', tu dois vider le buffer de saisie par un while ((c = fgetc(stdin)) != '\n') ;
Marsh Posté le 22-11-2006 à 08:13:27
exhortae a écrit : voilà je commence à toucher un petit peu aux pointeurs, et j'ai un petit problème avec le programme suivant. Il est censé permettre la saisie d'une liste de nom, les trier puis les afficher par ordre alphabétque. Le soucis c'est que lors de la saisie (juste après que je rentre le nombre de nom à saisir) et bien le gets me saute la saisie d'un nom |
Il ne faut pas utiliser gets(). Les saisies en C demandent de l'attention.
Je recommande une utilisation exclusive et maitrisée de fgets().
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers
Ton code commenté et corrigé. Bien lire les commentaires (-ed-) et poser des questions si nécessaire.
Code :
|
Le fonctionnement est maintenant conforme :
Entrez le nom a saisir : ljksd lkjsd Entrez le nom a saisir : jkdfi ds Entrez le nom a saisir : unazlmdj kclkds Entrez le nom a saisir : sdf ryuihdf JKDFI DS |
Mais le tri est améliorable. En effet, on a un tableau de pointeurs. Il suffit donc d'échanger les pointeurs au lieu des chaines, ce sera bien plus rapide.
Enfin, le code, tel qu'il est présenté maintenant grâce à la réduction massive de la portée des variables, peut être découpé facilement en fonctions, ce qui le rendra nettement plus clair, en introduisant un nouveau niveau d'abstraction.
Code :
|
On pourrait aller plus loin dans l'abstraction, mais pour le moment, ça devrait suffire.
Pose des questions si tu ne comprends pas.
Marsh Posté le 22-11-2006 à 20:51:27
Trap D a écrit : Tu cumules deux problèmes : |
Merci
Marsh Posté le 22-11-2006 à 20:53:09
Emmanuel Delahaye a écrit : On pourrait aller plus loin dans l'abstraction, mais pour le moment, ça devrait suffire. |
Vraiment un grand merci à toi d'avoir pris autant de temps pour me répondre,
je potasse ça à tête reposée et je reviens
encore une fois merci
Marsh Posté le 23-11-2006 à 23:01:21
Me revoilà
voilà j'ai lu, et essayer d'appliquer (en partie pour commencer), tes conseils.
je n'ai pas suivi toutes le recommandations parceque j'aimerais y aller progressivement, voilà j'ai réecri le programme une première fois, si tu pouvais d'abord me dire si c'est correct (par si c'est correct j'entends si il n'y a pas d'erreur, pas si certaines chose sont manquantes ). Ensuite j'aimerais te poser dessus quelques questions si tu veux bien.
Merci
Code :
|
Marsh Posté le 23-11-2006 à 23:47:47
exhortae a écrit : je n'ai pas suivi toutes le recommandations parceque j'aimerais y aller progressivement, voilà j'ai réecri le programme une première fois, si tu pouvais d'abord me dire si c'est correct (par si c'est correct j'entends si il n'y a pas d'erreur, pas si certaines chose sont manquantes ). |
Le fonctionnement est correct, mais la mémoire n'est pas libérée. Si je passe ton code au détecteur de mensonges :
|
Il avoue n'avoir pas libérer la mémoire...
Citation : Ensuite j'aimerais te poser dessus quelques questions si tu veux bien. |
OK.
Marsh Posté le 24-11-2006 à 15:18:33
Bonjour,
alors j'ai d'abord une question sur les fonctions d'entrée en c.
Voilà je vais commencer à utiliser fgets à la place de scanf.
Si j'ai bien compris après un fgets il faut utiliser ta fontion fclean (pour vider le flux stdin ??), et c'est la où j'ai un problème, j'ai pas très bien saisie le principe de ta fonction fclean.
La fonction prends comme paramètre la chaine que j'ai récupérer avec fgets, et le flux (stdin dans mon cas), Mais l'autre paramètre (FILE * fp) j'ai pas saisi ce que c'est.
2) toujours dans la fonction fclean,
Code :
|
est-ce que ça veut dire je recherche la sous chaine \n dans la chaine s, et je l'affecte à p le cas échéant???
3) dans
Code :
|
la première condition signifie si dans la chaine s il y a le caractère '\n', *p = 0
mais concrètement ça veut dire quoi *p = 0;
et ce qu'il y a dans le else pour être honnête j'ai rien compris
Merci
PS : pendant que j'y suis , tu connaitrais un editeur, compilateur exécuteur pour le c sous windows.
Un truc avec une interface à peu près potable (pas comme turbo c 2.x et son interface rébarbative sur un lcd)
Marsh Posté le 24-11-2006 à 15:33:29
exhortae a écrit : Voilà je vais commencer à utiliser fgets à la place de scanf. |
Bonne idée.
Citation : Si j'ai bien compris après un fgets il faut utiliser ta fontion fclean (pour vider le flux stdin ??), |
entre autres...
Citation : et c'est la où j'ai un problème, j'ai pas très bien saisie le principe de ta fonction fclean. |
Attention, j'ai mis 10 à mettre au point cet algorithme :
"Chercher le '\n. Si il est présent, l'éliminer, sinon lire les caractères non lus sans les stocker."
Puissant, non ?
Pour les détails d'implémentation, je suggère que tu lises la doc des fonctions. (livre de C, man, help, F1, google...)
Citation : la première condition signifie si dans la chaine s il y a le caractère '\n', *p = 0 |
Yo !
Citation : mais concrètement ça veut dire quoi *p = 0; |
A ton avis ? Vraiment aucune idée ?
EDIT: je voudrais pas dire, mais mon code était commenté. Tu ne comprends pas l'anglais ? Pas d'informatique sans savoir lire l'anglais.
Citation : tu connaitrais un editeur, compilateur exécuteur pour le c sous windows. |
Je recommande Code::Blocks http://www.codeblocks.org/
Marsh Posté le 25-11-2006 à 20:27:58
Emmanuel Delahaye a écrit : je voudrais pas dire, mais mon code était commenté. Tu ne comprends pas l'anglais ? Pas d'informatique sans savoir lire l'anglais. |
Je me débrouille plutôt bien en anglais, c'est juste qu'avec les pointeurs, j'ai du mal, mais là c'est bon, j'ai saisie la fonction et je suis capable de la refaire sans l'avoir apprise.
sinon voilà j'ai essayé d'appliquer tes conseils en faisant un ptit programme qui conjuge certains verbes du premier groupe, par contre j'ai du mal au niveau du main(), lorsque j'utilise une procédure qui devrait me permettre de tronquer mon verbe. c'est la procédure tronquer qui recoit comme paramètre une chaine de caractère et renvoie la chaine de caractère tronquée, y doit y avoir un soucis de pointeur
voilà le code
Code :
|
Marsh Posté le 25-11-2006 à 20:50:39
Après recherche plus poussée et différents essais, j'ai remplacer mon main () par ça, et là ça marche, par contre je me demande si c'est correct.
Code :
|
Marsh Posté le 26-11-2006 à 01:32:57
exhortae a écrit :
|
Interdit. Tu n'a pas le droit d'utiliser strcpy() sur le le même tableau. Pour ça, il faut utiliser memmove(). (Lire la doc de ces deux fonctions pour les détails).
Je ne vois pas pourquoi tu passes l'adresse du pointeur. Tu ne le modifie pas. C'est l'objet pointé que tu modifies. Tu peux donc écrire (le strcpy() reste faux):
Code :
|
Enfin, un 'tronquage' ne nécessite pas de recopie. Tu peux donc simplifier comme ceci :
Code :
|
Il faudrait prendre cependant quelques précautions comme :
Code :
|
Je pense que si une phase de conception avait été réalisée, on aurait écrit le bon code directement...
D'ailleurs ça s'applique à l'ensemble du programme dont le codage me parait bien compliqué, malgré un main() prometteur, il faut le souligner... J'aimerais bien voir le document de conception...
Marsh Posté le 29-11-2006 à 22:46:38
Je met en suspend ce sujet vu que je viens de tomber sur un cours qui explique les pointeurs de zéro (j'ai pas mal de difficultés avec). le temps de l'étudier et je reviens au travail précédent
Marsh Posté le 22-11-2006 à 07:54:36
Bonjour,
voilà je commence à toucher un petit peu aux pointeurs, et j'ai un petit problème avec le programme suivant. Il est censé permettre la saisie d'une liste de nom, les trier puis les afficher par ordre alphabétque.
Le soucis c'est que lors de la saisie (juste après que je rentre le nombre de nom à saisir) et bien le gets me saute la saisie d'un nom
au lieu d'afficher
Entrez le nom a saisir :
il me fait
Entrez le nom a saisir :
Entrez le nom a saisir :
et donc au lancement de la boucle je perds la saisie d'un nom. Je sais pas si j'ai été assez clair.
voilà le programme, si quelqu'un pouvait me filer un ptit coup de main pour trouver ce qui ne vas pas
Merci