Besoin d'aide pour un exercice. - C - Programmation
Marsh Posté le 29-12-2004 à 19:28:51
Un réponse en vitesse, il faut faire attention à la priorité entre * et ++ : "*ifmot++;" ==> "(*ifmot)++;"
Sinon ton source est *vraiment* pas clair (IOCCC ? Non, je suis méchant).
Regarde aussi du côté de "strchr()", "strpbrk()" et autres...
Marsh Posté le 29-12-2004 à 19:33:55
lsdyoyo a écrit : Un réponse en vitesse, il faut faire attention à la priorité entre * et ++ : "*ifmot++;" ==> "(*ifmot)++;" |
Merci, j'ai effectué cette correction, et maintenant j'ai une erreur similaire mais ailleurs, je vais faire un debuggage pas à aps pour voir ou exactement...
Euh... c'est pas clair à ce point la ?
strchr() et strpbrk() je connais pas, mais vu que c'est un exo si je sors ca mes profs ils vont me regarder comme ca:
EDIT: lol j'arrive meme plus a generer mon prog sans les corrections alors qu'avant ca se faisait nickel
Marsh Posté le 29-12-2004 à 22:07:51
D'après ce que j'ai pu comprendre, la fonction SIZEMOT sert à calculer la position de debut (idmot) et de fin (ifmot) du dernier mot d'une chaine, en tenant compte des ponctuations.
Voici une solution alternative. A tester pour voir si c'est bien ce que tu recherches.
Code :
|
Marsh Posté le 29-12-2004 à 22:39:35
pains-aux-raisins a écrit :
|
Le premier test ne serait pas à l'envers? Et avec une chaine du genre "foo" on va avoir des index négatifs
Marsh Posté le 29-12-2004 à 22:52:01
nan, notre ami initialise la variable *ifmot avec strlen(vers)... va savoir pourquoi...
Marsh Posté le 29-12-2004 à 22:59:46
pillow a écrit : Le premier test ne serait pas à l'envers? Et avec une chaine du genre "foo" on va avoir des index négatifs |
j'ai compris ce que tu voulais dire... D'ailleurs ça doit être la cause de sa violation d'adresse
Code :
|
Marsh Posté le 29-12-2004 à 23:01:02
pains-aux-raisins a écrit : nan, notre ami initialise la variable *ifmot avec strlen(vers)... va savoir pourquoi... |
Ben... pour partir de la fin ?
(Puisque en effet je veux les indices de debut et de fin du dernier mot)
Marsh Posté le 29-12-2004 à 23:08:04
je viens de modifier le code de SIZEMOT pour gérer les cas limites. A toi maintenant de vérifier qu'ils n'en restent pas d'autres
Marsh Posté le 29-12-2004 à 23:12:25
pains-aux-raisins a écrit : j'ai compris ce que tu voulais dire... D'ailleurs ça doit être la cause de sa violation d'adresse
|
Le premier test me semble toujours à l'envers
Le but c'est qu'avec une chaine du type "foo:bar!!!", on récupère 4 et 7, non?
Dans ce cas, on commence par la fin, on boucle jusqu'a trouver la fin du dernier mot (donc tant que ispunc est vraie). Puis on boucle jusqu'a trouver le début du dernir mot (donc tant que ispunct est fausse) .
Pour la violation d'accès je pense que ça venait plutot de la priorité entre * et --
Ça devrait donner ça donc:
Code :
|
(Il y avait une * de trop dans le deuxième test )
Marsh Posté le 29-12-2004 à 23:41:20
Merci bcp pour vos reponses !
En effet la violation d'acces venait de la priorité entre * et -- (que j'ignorais jusqu'à maintenant).
C'est vrai que j'avais pas pensé à faire une fonction avec un switch, merci aussi pour cette methode
Marsh Posté le 30-12-2004 à 00:00:41
pillow a écrit :
|
Euh... c'est ptet pas une bonne idée de mettre --*ifmot dans vers[] parce que si *ifmot=0, on va s'aventurer dans un vers[-1]
Marsh Posté le 30-12-2004 à 00:40:53
pains-aux-raisins a écrit :
|
ispunct() est une fonction standard (<ctype.h> ). Inutile de réinventer la roue...
http://dpobel.free.fr/man/html/affiche_man.php?id=1480
Marsh Posté le 30-12-2004 à 01:38:17
Emmanuel Delahaye a écrit : ispunct() est une fonction standard (<ctype.h> ). Inutile de réinventer la roue... |
D'apres la page que tu a envoyé ispunct() ne sépare que espace&alpha-numériques et autres, or la c un peu différent... Et puis dans mon exo c'était dit clairement quels caracteres servaient de separation entre les mots.
Sinon pourquoi int ispunct(int car) et pas int ispunct(char car) ?
Marsh Posté le 30-12-2004 à 07:41:33
mcyrb a écrit : D'apres la page que tu a envoyé ispunct() ne sépare que espace&alpha-numériques et autres, or la c un peu différent... Et puis dans mon exo c'était dit clairement quels caracteres servaient de separation entre les mots. |
Alors utilise un vieux:
Code :
|
Marsh Posté le 30-12-2004 à 08:50:34
c'est la solution qu'on utiliserai dans la vraie vie, mais je crois me souvenir que les profs aiment bien réinventer la roue
Marsh Posté le 30-12-2004 à 08:52:09
Emmanuel Delahaye a écrit : ispunct() est une fonction standard (<ctype.h> ). Inutile de réinventer la roue... |
Merci Emmanuel Delahaye, tu viens de changer ma vie...
Marsh Posté le 30-12-2004 à 08:57:26
pillow a écrit : Le premier test me semble toujours à l'envers |
+1
Il était tard disons...
Marsh Posté le 30-12-2004 à 09:04:21
mcyrb a écrit : Euh... c'est ptet pas une bonne idée de mettre --*ifmot dans vers[] parce que si *ifmot=0, on va s'aventurer dans un vers[-1] |
Met les *ifmot>=0 et idmot>= avant le test ispunct. Ton compilateur étant un peu fainéant n'ira pas faire le test ispunct si *ifmot ou idmot est négatif.
Modifie le code posté pillow pour gérer le cas d'un vers ne contenant qu'un seul mot, sans ponctuation.
(dans ce cas le début c'est 0 et la fin c'est la longueur de la chaine - 1)
Marsh Posté le 30-12-2004 à 11:54:34
pains-aux-raisins a écrit : Met les *ifmot>=0 et idmot>= avant le test ispunct. Ton compilateur étant un peu fainéant n'ira pas faire le test ispunct si *ifmot ou idmot est négatif. |
Ouais, mais meme en mettant *ifmot>=0 et idmot>=0 avant, la décrémentation va se faire apres ce test... ou alors faudrait remplacer >= par >
Marsh Posté le 30-12-2004 à 11:59:24
hmm, pour des raisons de simplicité, je mettrais tout bêtement la décrémentation dans le corps de la boucle...
J'aime pas me prendre la tête pour des trucs qui n'en valent pas la peine.
en gros je reprendrais le do...while que j'avais posté, corrigé par la remarque de pillow.
Marsh Posté le 30-12-2004 à 12:59:43
pains-aux-raisins a écrit : hmm, pour des raisons de simplicité, je mettrais tout bêtement la décrémentation dans le corps de la boucle... |
C'est ce que j'ai fait
Marsh Posté le 30-12-2004 à 13:00:58
Lam's a écrit : Alors utilise un vieux:
|
Le probleme c'est que pour moi il est pas vieux, il est meme pas nouveau, il m'est encore (officiellement) inconnu
Marsh Posté le 30-12-2004 à 14:03:44
salut,
g essayé ton code de la façon suivante et ça m'a pas posé de pbr, il est executable et il m'a affiché les valeurs de ifmot et idmot
#include <stdio.h>
#include <conio.h>
#include <string.h>
int SIZEMOT(char *vers,int *ifmot)
{
char T[11]={' ','.','!','?','\'',',',';',':','(',')','"'};
int idmot,i;
do
{
*ifmot--;
for(i=0;i<11 && vers[*ifmot]!=T[i];i++);
}
while(i!=11);
idmot=*ifmot;
do
{
idmot--;
for(i=0;i<11 && vers[idmot]!=T[i];i++);
}
while(i==11);
idmot++;
*ifmot++;
return(idmot);
}
void main()
{
char vers[81];
int idmot,ifmot;
gets(vers);
ifmot=strlen(vers);
idmot=SIZEMOT(vers,&ifmot);
printf("%d %d", ifmot, idmot);
getch();
}
dis moi est ce que ce que tu veux faire vraiment ça ou non. moi, bien que g pas bien lu le code, g une doute concernant le gets, est ce que t'es sûr qu'elle est entrain de vraiment lire la chaine de carctères, probalement le stdin est plein donc il n'est pas entrain de recevoir la chaîne, je pense que tant qu'il y a une violation d'accès, il y a un pointeur NULL en jeux.
donc pour eviter ce prb , fais précéder l'instruction gets(vers);
par fflush(stdin);
j'attends ta réponse!!
Marsh Posté le 30-12-2004 à 15:33:46
ssou a écrit : salut, |
Une façon compliquée d'écrire
char T[11] = " .!?',;:()\"";
Citation : void main() |
main() retourne int. Toujours.
Citation : gets(vers); |
gets() est un bug. Son utilisation est formellement déconseillé.
Citation : donc pour eviter ce prb , fais précéder l'instruction gets(vers); |
gets() n'est pas une instruction mais un appel de fonction.
fflush() n'est défini que pour les flux sortants.
Marsh Posté le 30-12-2004 à 16:09:10
salut,
je sais bien que gets est une fonction de lecture de chaine de caractères, mais toute la ligne gets(chaine); est une instruction en soi.
elle n'est pas déconseillée, je suis désolée, car pour la lecture d'une chaine de caractères il n'y a pas mieux, sinon quelle sont les autres alternatives? tu vas me dire scanf, et ben, scanf elle est "forte" pour le faite qu'elle permet de lire tt type de données mais son problème majeur avec les chaînes de caractères c qu'elle ne lit qu'une chaine qui ne contient pas d'espace blanc (elle s'arrête dès qu'elle trouve un espace blanc),et donc son utilisation devient limitée.
concernant le fflush, desolée aussi, elle est utilisable pour les flux d'entrée ainsi que les flux de sortie
fflush(stdin); pour les flux d'entrée
fflush(stdout); pour la sortie
main ne retourne pas tjr un int comme tu le dis, elle peut retourner un void.
et tu peux expériementer ça!
Marsh Posté le 30-12-2004 à 16:46:47
ssou a écrit : |
fgets()
http://mapage.noos.fr/emdel/notes.htm#saisie
Citation : |
Non. La norme est claire:
Citation : |
Citation : |
http://mapage.noos.fr/emdel/notes.htm#typemain
Essayons :
|
Borland C 3.1
|
Dev-C++
|
Marsh Posté le 30-12-2004 à 17:24:37
ssou a écrit : salut, |
Je n'ai plus aucun probleme avec cette fonction, elle execute exactement ce que je lui demande, merci quand meme.
(Le but de mon programme n'est pas d'afficher les positions de debut et de fin du dernier mot, mais juste de cette fonction, enfin j'ai d'autres problemes dans mon prog mais qui n'ont plus rien à voir avec cette fonction).
Marsh Posté le 30-12-2004 à 17:28:31
Sinon en rapport avec votre discussion, moi pour le moment on m'a toujours dit de déclarer le main avec void main(), d'utiliser un gets() pour saisir une chaine de caracteres et d'utiliser un fflush(stdin); lorsque je veux faire un gets apres avoir fait un scanf() et/ou un getchar().
Pour cette histoire de norme j'en entends beaucoup parler, enormément meme, dapres ce que j'entends, je ne fais que des choses déconseillées voire interdites, mais bon pour l'instant je fais comme on me l'apprend et tant qu'il y a pas de probleme...
EDIT: Et ca fonctionne tres bien sous Dev C++ (que j'ai utilisé) et Visual C++ 6.0 et .NET (que j'utilise actuellement).
Marsh Posté le 30-12-2004 à 17:41:06
mcyrb a écrit : moi pour le moment on m'a toujours dit de déclarer le main avec void main(), d'utiliser un gets() pour saisir une chaine de caracteres et d'utiliser un fflush(stdin); |
Je ne sais pas qui est ce 'on', mais moi, et d'autres (y compris ceux qui écrivent les compilateurs) nous te disons ce qui est défini dans la norme. Bien sûr il existe des tonnes de bouquins et des masses de soi-disant profs se copiant les uns les autres pour soutenir le contraire, mais les professionels, notamment les nombreux contributeurs du forum Usenet news:comp.lang.c savent de quoi ils parlent et ont dénoncé ces pratiques douteuses depuis la nuit des temps.
Quelques liens:
http://membres.lycos.fr/cultc/liens_prog.htm
Citation : |
Ben oui. Le langage C est normalisé. La moindre des choses si on utilise se langage est au, moins de savoir ce qui est spécifié et ce qui ne l'est pas.
Citation : |
Tu fais ce que tu veux, mais en connaissance de cause.
Ne fait pas ça si des vies sont en cause (automobile, médical, avionique, nucléaire, spatial). Tous ces domaines utilisent de l'informatique embarquée, principalement écrite en C ou en Ada...
Marsh Posté le 30-12-2004 à 17:48:12
Emmanuel Delahaye a écrit : Je ne sais pas qui est ce 'on', mais moi, et d'autres (y compris ceux qui écrivent les compilateurs) nous te disons ce qui est défini dans la norme. |
Ben 'on' ce sont mes profs d'algo, mais en meme temps je ne suis qu'au premier trimestre de 1re année donc je pretends pas du tout etre capable de programmer pour le professionnel... peut etre que cette histoire de norme viendra plus tard, mais c'est dommage que ce serait dommage quece soit ignoré dans une formation professionnelle
Marsh Posté le 30-12-2004 à 17:57:11
mcyrb a écrit : Ben 'on' ce sont mes profs d'algo, mais en meme temps je ne suis qu'au premier trimestre de 1re année donc je pretends pas du tout etre capable de programmer pour le professionnel... peut etre que cette histoire de norme viendra plus tard, mais ce serait dommage que ce soit ignoré dans une formation professionnelle |
L'enseignement est malheureusement très mauvais... Tout ce que j'ai appris, c'est par 15 ans de formation autodidacte et de pratique personnelle et professionelle, une semaine de stage intensif de C (sur 8 mois de stage d'informatique de gestion), et 5 ans de pratique des forums C pointus comme clc et flc.
Marsh Posté le 30-12-2004 à 18:14:48
je suppose que tout le monde est d'accord pour taper sur l'éducation.
Mais on est combien à avoir envoyé chier tout ce bordel et à en subir les conséquences (notament salariales) ?
Marsh Posté le 30-12-2004 à 18:24:13
nraynaud a écrit : je suppose que tout le monde est d'accord pour taper sur l'éducation. |
Je pense sincèrement que le travail bénévole que font les intervenants sérieux des forums techniques sont une réponse 'citoyenne et responsable' aux manquements graves de l'enseignement.
Personnellement, mon but est que les gens programment mieux. J'ai été confronté à trop de code poubelle que j'ai du réécrire de A à Z pour ne pas essayer d'améliorer les choses...
Alors SVP, plus de gets(), ni de fflush(stdin)...
Marsh Posté le 29-12-2004 à 19:10:27
Voila, j'ai un exo à faire en C et j'ai une fonction qui merde...
Mon programme se genere sans probleme mais au moment de l'execution j'ai une erreur qui me dit:
Exception non gérée à 0x00412083 dans monprog.exe:0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0xccdfcb40.
Voila la fonction en question:
Et voila la partie de la fonction principale qui contient cette fonction:
Merci pour votre aide
Message édité par mcyrb le 29-12-2004 à 19:18:53