Salut,
j'aimerais savoir si quelqu'un aurait un lien(ou plusieurs)sur le langage C à me recommander qui exlique bien les notions de pointeurs et de fichiers car c'est pour réviser pour mes examens .
Merci d'avance
Salut,
j'aimerais savoir si quelqu'un aurait un lien(ou plusieurs)sur le langage C à me recommander qui exlique bien les notions de pointeurs et de fichiers car c'est pour réviser pour mes examens .
Merci d'avance
Sur ce même site, rubrique Tutos:
http://c.developpez.com/cours/
Bonjour,
j'aurais besoin d'aide pour ces différents exercices
Merci d'avance
Il aurait fallu écrireExpliquer en quoi le commentaire est faux
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 /* Write 6 integers to a disk file */ void put_rec(int rec[6], FILE *fp){ int len; len=fwrite(rec, sizeof rec, 1, fp); if(len != 1) printf("write error"); }On ne vérifie pas si le fichier est correctement ouvert.
Code : Sélectionner tout - Visualiser dans une fenêtre à part fwrite(rec,sizeof int,6,fp)
L'avertissement du compilateur indique qu'en ligne 4 du programme la fonction g fait appelle à une fonction f qui n'a pas été déclaré dans ce fichier.Que signifie l’avertissement du compilateur
Comment y rémédier?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2Warn.c : In function g Warn.c:4: warning: implicit déclaration of function f
Pour y remédier,il faut écrire la fonction f correspondante ou bien d'arranger pour ne pas utiliser cette fonction f
J'ai du mal pour ceciQue fait le programme suivant ?
Est’il portable(justifiez votre réponse)
Que se passe t’il si la saisie n’est pas correcte ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<limits.h> int etrange(unsigned long int x){ return x>9UL ? -1 : 0+ (int)x; } char *bizarre(unsigned long int x, unsigned int z, unsigned long int d){ static char y[BUFSIZ];/* On suppose BUFSIZ suffisamment grand*/ int k= etrange (x/d); if(k!=-1) y[z+1]=\0 ; else{ (void)bizarre(x, z+1U, d*10UL); k= etrange ((x/d)%10UL); } y[z]=(char)k ; return y ; } char *mystere(unsigned long int x){ return bizarre(x, OU, 1UL); } int main(int argc, const char *argv[]){ unsigned long ul; char *e; if(argc != 2){ fprintf(stderr,"Erreur: nombre de parametres incorrects ! \n " ) ; return EXIT_FAILURE. } errno=0 ; ul=strtoul(argv[1],&e,10); if((ul==ULONG_MAX && errno==ERANGE) || (*e != \0)){ fprintf(stderr,"Erreur: nombre de traitement du parametre ! \n " ) ; return EXIT_FAILURE. } printf(" s\n" ,mystere(ul)) ; return EXIT_SUCCESS; }
Cette ligne est bizarre...
Code : Sélectionner tout - Visualiser dans une fenêtre à part if((ul==ULONG_MAX && errno=ERANGE) || (*e != '\0'){
1) Il y a une affectation dans l'expression conditionnelle (errno=ERANGE)
2) Ne compile pas (manque une parenthèse fermante)
En fait, ça joue beaucoup sur les types et les tailles d'entier, mais de là à savoir si c'est portable ou non, il faudrait regarder cela de plus près pour savoir si cela dépend de tailles non-spécifiées dans la norme ou pas...
PS: Sinon, c'est pas facile à voir, surtout que ça utilise un appel récursif, et des noms de variable bien peu explicites...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Les erreurs sont de ma faute car j'ai retapé le code à la main (sans utiliser de compilateur)Envoyé par Médinoc
J'ai édité.
S'il y d'autres parentheses manquantes ... c'est de ma faute car le programme marche mais je n'arrive pas à savoir ce qu'il fait
On n'est pas là pour répondre à tes exercices... Ce n'est pas le but de ce forum... Il est là pour aider lorsqu'il y a un problème direct avec le C... Donc on ne peut/veut pas répondre directement et donc résoudre directement tes questions...
Par contre, les réponses à tes 2 premiers exos sont faux:
1) On ne te demande pas de corriger la faute mais de dire pourquoi le commentaire est faux. Tu as réussi à voir que c'est ici l'erreur...
Pourquoi est-ce faux? (ta réponse n'est pas plus juste d'ailleurs)
Code : Sélectionner tout - Visualiser dans une fenêtre à part fwrite(rec, sizeof rec, 1, fp);
2)C'est faux, la fonction f peut très bien être dans ce fichier mais où par rapport à g?une fonction f qui n'a pas été déclaré dans ce fichier.
Jc
Bonjour,
j'ai modifié mes réponses que voici
Merci de bien vouloir corriger mes erreurs
Le code est faux car :Expliquer en quoi le commentaire est faux
Justifiez votre réponse.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 /* Write 6 integers to a disk file */ void put_rec(int rec[6], FILE *fp) { int len; len = fwrite(rec, sizeof rec, 1, fp); if(len != 1) printf("write error"); }
ecrit dans le fichier fp un un tableau de 6 entiers
Code : Sélectionner tout - Visualiser dans une fenêtre à part fwrite(rec, sizeof rec, 1, fp);
L'avertissement du compilateur indique qu'en ligne 4 du programme la fonction g fait appelle à une fonction f qui n'a pas été déclaré dans ce fichier ou alors que la fonction f est déclaré après la fonction g (dans le meme fichier)Que signifie l’avertissement du compilateur
Comment y rémédier?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2Warn.c : In function g Warn.c:4: warning: implicit déclaration of function f
Pour y remédier,il faut écrire la fonction f correspondante avant la fonction g ou bien s'arranger pour ne pas utiliser cette fonction f
Le programme suivant lit une chaine de caractère entrée au clavier,la convertit en unsigned long puis renvoie l'entier long sous forme de chaine de caracère en ordre inverse.Que fait le programme suivant ?
Est’il portable(justifiez votre réponse)
Que se passe t’il si la saisie n’est pas correcte ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<limits.h> int etrange(unsigned long int x) { return x>9UL ? -1 : '0'+(int)x; } char *bizarre(unsigned long int x, unsigned int z, unsigned long int d) { static char y[BUFSIZ];/* On suppose BUFSIZ suffisamment grand */ int k= etrange (x/d); if(k != -1) y[z+1] = '\0'; else { (void)bizarre(x, z+1U, d*10UL); k = etrange ((x/d)%10UL); } y[z]=(char)k; return y ; } char *mystere(unsigned long int x) { return bizarre(x, 0U, 1UL); } int main(int argc, const char *argv[]) { unsigned long ul; char *e; if(argc != 2) { fprintf(stderr,"Erreur: nombre de parametres incorrects ! \n " ) ; return EXIT_FAILURE; } errno=0; ul=strtoul(argv[1],&e,10); if((ul == ULONG_MAX && errno == ERANGE) || (*e != '\0')){ fprintf(stderr,"Erreur: nombre de traitement du parametre ! \n " ) ; return EXIT_FAILURE; } printf("%s\n" ,mystere(ul)) ; return EXIT_SUCCESS; }
Si la saisie n'est pas correcte,le message suivant s'affiche:
Portable ?Erreur: nombre de traitement du parametre !
Dans le main,l'erreur provient de ceci:L'éxécution du programme suivant produit une erreur de segmentation.Expliquez pourquoi
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 #include<stdio.h> #include<stdlib.h> #include<string.h> size_t monStrlen(const char *p) { size_t len = 0; while (*(p++) != '\0'); ++len; return len; } int monStrcmp(const char **x, const char **y) { /* strcmp prend en parametres deux char* */ return strcmp(*x,*y); } void suppDoublons(char *t[], size_t nbElts) { unsigned int i = 0U; while(i<nbElts-1) { if(strcmp(t[i],t[i+1])==0) { unsigned int j; for(j=i; j<nbElts-1; ++j) t[j] = t[j+1]; --nbElts; t[nbElts] = NULL; } else ++i; } } int main(int argc, char *argv[]) { unsigned int i; char **tab; if(((tab)=(char **)malloc((argc-1)*sizeof(char *)))==NULL) { perror("Allocation tab:"); return EXIT_FAILURE; } for(i=1U; i<argc; ++i) tab[i-1] = argv[i]; qsort(tab,(size_t)(argc-1),sizeof(char *), (int(*)(const void*, const void*))monStrcmp); for(i=0; i<argc-1; ++i) printf("%s %d\n",tab[i],monStrlen(tab[i])); suppDoublons(tab,(unsigned int)(argc-1)); printf("----\n"); for(i=0; i<argc-1; ++i) printf("%s %d\n",tab[i],monStrlen(tab[i])); free(tab); return EXIT_FAILURE; }
L'erreur est ici car on affecte à chaque tab[i-1] la valeur de argv[i] mais on ne vérifie pas si chaque case du tableau tab est de taille suffisament grande pour contenir la valeur argv[i].
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 for(i=1U; i<argc; ++i) tab[i-1] = argv[i];
Il aurait fallu écrire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 for(i=1U; i<argc; ++i) { tab[i] = (char*)malloc(strlen(argv[i]+1)); if(tab[i] == NULL) { fprintf(stderr,"Erreur allocation memoire\n"); return EXIT_FAILURE; } strcpy(tab[i-1],argv[i]); }
Voici mes commentaires:
Si tu penses que c'est ce que fait le programme alors le commentaire est juste donc la question n'a pas de sens... Je t'affirme que la question a un sens donc ta compréhension du code est fausse...Envoyé par Gryzzly
On te demande si le code peut fonctionner sur n'importe quel ordinateur, est-ce qu'il aura des problèmes de compilations ou d'exécution sur une machine Windows, Linux, Unix?Portable ?
La dernière question:
et tu réponds:L'éxécution du programme suivant produit une erreur de segmentation.Expliquez pourquoi
C'est faux, on copie juste le pointeur rien de plus, le tableau est assez grand... Commence par mettre toutes les instructions du main entre commentaire et enlève les doucement... Tu devrais trouver l'erreur... Dans ce code, j'en vois 4, trois qui peuvent entraîner un segmentation fault et un dernier fait qu'on ne calcule pas la valeur qu'on voudrait...Dans le main,l'erreur provient de ceci:
L'erreur est ici car on affecte à chaque tab[i-1] la valeur de argv[i] mais on ne vérifie pas si chaque case du tableau tab est de taille suffisament grande pour contenir la valeur argv[i].
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 for(i=1U; i<argc; ++i) tab[i-1] = argv[i];
Je te conseille de regarder quand est-ce qu'il fait un segmentation fault est-ce que:
en fait un?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ./supp
ou
ou encore
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ./supp aa bb cc
Jc
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ./supp aa bb cc aa
Pour le ./supp ,il y a un seg fault car il n'y a pas de message d'erreur si aucun parametre n'est entré.Envoyé par fearyourself
La fonction ne renvoie pas ce qu'elle devrait dans le cascar la comparaison a lieu sur des elements "cote à cote" .
Code : Sélectionner tout - Visualiser dans une fenêtre à part ./supp aa bb cc aa
Le seg fault est du à ceci :
car les bornes d'affiche n'est pas la bonne car la fonction suppDoublon à réduit le nombre d'élement de la table
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 for(i=0; i<argc-1; ++i) printf("%s %d\n",tab[i],monStrlen(tab[i]));
Et c'est à quel endroit que le segmentation fault se produit?Pour le ./supp ,il y a un seg fault car il n'y a pas de message d'erreur si aucun parametre n'est entré.
C'est faux car ceci est fait avant:car la comparaison a lieu sur des elements "cote à cote" .
Qsort est une fonction de tri donc ton tableau est trié... Mais:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 qsort(tab,(size_t)(argc-1),sizeof(char *), (int(*)(const void*, const void*))monStrcmp);
là tu as raison...car les bornes d'affiche n'est pas la bonne car la fonction suppDoublon à réduit le nombre d'élement de la table
[quote]Ici dès la 1ère boucleEnvoyé par fearyourself
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 for(i=1U; i<argc; ++i) tab[i-1] = argv[i];Il manque un & avant le monStrcmp pour recupérer l'adresse de la fonctionQsort est une fonction de tri donc ton tableau est trié... Mais:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 qsort(tab,(size_t)(argc-1),sizeof(char *), (int(*)(const void*, const void*))monStrcmp);
Faux, i commence à 1 et argc == 1 donc on ne rentre pas dans la boucle...Ici dès la 1ère boucle
Je dois avouer ne m'être jamais posé sur ce problème (ie chercher la raison mais je sais que sur les ordinateurs sur lesquels je code ceci marche...). C'est ce que j'aime de ce forum, on découvre des détails tous les jours sur le langage CIl manque un & avant le monStrcmp pour recupérer l'adresse de la fonction:
C'est peut-être une question de compilateur mais ce code va afficher la même chose pour la fonction et pour le pointeur de texte... Donc ce n'est pas le fait d'oublier le & qui pose problème, qsort marchera très bien, du moins sur mes machines...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <stdio.h> #define TXT "bonjour" int f() {return 1;} int main() { printf("%p %p\n",f,&f); printf("%p %p\n",TXT,&TXT); return 0; }
Jc
J'ai pas tout saisie concernant les endroits provoquant le seg fault dans le programme .
A part,le fait qu'il n' y a pas de test d'erreur si rien n'est saisie quelles sont les autres erreurs ?
Edit :l'erreur se produit lors du malloc argv-1 -> -1 s'il n'y a pas de chaine de caracteres qui sont entrees
Nous ne sommes pas là pour résoudre tes exercices... Comme tu as remarqué, je réponds lorsque tu proposes quelque chose mais je ne résolverais pas ton exercice... C'est en cherchant que tu comprendras mieux...
Je crois même t'avoir dit combien d'erreurs il y avait à trouver (sauf si j'en ai loupé)...
Utilises un debugger ou mets des printf pour trouver les endroits à problème...
Indice:
Il y a une erreur de frappe dans monStrlen
Il y a une erreur de vérifications dans suppDoublons lorsqu'on fait ./supp
Il y a une erreur de logique dans le main que tu as trouvé, la taille de tableau n'est pas mis à jour
Jc
PS: En fait c'est tout ce que je vois maintenant, je ne sais plus pourquoi je disais 4, cela me reviendra peut-être...
Bonjour ,
j'aurais besoin d'une correction pour le problème que voici.
Merci d'avance
Problème
Dans le problème nous manipulons des tas.Un tas est un conteneur de données,qu'on peut représenter comme un arbre dont la racine contient à chaque instant le plus petit élément du conteneur (on note que cela suppose qu'il existe une relation d'ordre sue les éléments).Ainsi ,l'opération “retrouver le plus petit élément” se réalise toujours en temps constant .Nous allons nous servir des tas pour réaliser des tris sur des donnéés.
Pour ne pas implémenter les tas ,on récupère ( sur le Web,par exemple), un module C permettant de les manipuler.Ce module est composé d'un fichier heap.c contenant les définitions de fonctions de manipulation d'un tas,et d'un fichier heap.h dont le contenu est:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #ifndef _HEAP_H #define _HEAP_H typedef struct _heap { /*On se moque du contenu de la structure*/ } Heap; /*Toutes ces fonctions retournent 0 ssi pas d'erreur, un code d'erreur sinon*/ /*Création d'un tas .Le paramètre cmp permet de préciser la relation d'ordre sur ces éléments. Cplx : 0(1)*/ extern int newHeap(Heap **h, int (*cmp)(void *,void *)); /*Ajouter l'élément désigné par newElt au tas désigné par h. Fait une copie à usage interne de l'élément. Cplx : 0(log(nb d'éléments du tas)+taille élément)*/ extern int addToHeap(Heap *h, void *newElt); /*Retirer le plus petit élément du tas ,le recopier dans la zone désignée par res ,qu'on suppose suffisament grande. Cplx: 0(log(nb d'éléments du tas)+taille élément)*/ extern int removeSmallestFromHeap(Heap *h, void *res); /*Libérer les ressources occupées par le tas. au retour de la fonction, *h vaut NULL.Cplx: 0(nb d'éléments du tas)*/ extern int freeHeap(Heap **h); /*Ici ,le fichier contient d'autres déclarations de fonctions, qui ne nous intérressent pas */ ... #endifNous nous interdisons de mofifier ces fichiers: nous ne pouvons que les utiliser.
Dans les fonctions de comparaisons qu'on vous demande d'écrire dans le problème ,
les conventions pour la valeur sont les memes que pour strcmp.Exercice 1
Ecrire une fonction réalisant la comparaison de deux chaines de caractères suivant l'ordre lexicographique.Votre fonction devra avoir la signature suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part int cmpLexico(const char *s1, const char * s2);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int cmpLexico(const char *s1, const char *s2) { return strcmp(s1,s2); }Meme chose,mais pour l'ordre lexicographique inverse (cette fois-ci le nom de la fonction sera cmpInvLexico)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int cmpInvLexico(const char *s1,const char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); int i,j; char *tmp1,*tmp2; for(i=0; i<l1; i++) tmp1[i] = s1[l1-1-i]; tmp1[l1] = '\0'; for(j=0; j<l2; j++) tmp2[j] = s2[l2-1-j]; tmp2[l2] = '\0'; return (cmpLexico(tmp1,tmp2)); }Exercice 2
L'”ordre militaire” sur les mots est donné par le nombre des lettres des mots: moins un mot a de lettres ,plus il est petit pour l'ordre militaire.
Ecrivez une fonction réalisant la comparaison de deux chaines de caractères suivant l'ordre militaire.Votre fonction devra avoir la signature suivante:
Code : Sélectionner tout - Visualiser dans une fenêtre à part int cmpMilitaire(const char *s1, const char * s2);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 int cmpMilitaire(const char *s1, const char *s2) { size_t l1,l2; l1 = strlen(s1); l2 = strlen(s2); if(l1 == l2) return 0; else return l1<l2 ? -1 : 1 ; }Meme chose,mais pour l'ordre militaire inverse (cette fois-ci le nom de la fonction sera cmpInvMilitaire)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int cmpInvMilitaire(const char *s1, const char *s2) { return cmpMilitaire(s1,s2)); }
Exercice 3
On définit maintenant une relation d'ordre sur les chaines de caractères de la façon suivante. Soit u un mot. A partir de u, on calcule u' en ramenant les voyelles au début du mot ,sans en changer l'ordre. Par exemple,si u = xbygeak,alors u' = yeaxbgk. Soient deux mots u1 et u2 . On dit que u1 est plus petit que u2 si et seulement si u1' est plus petit,pour l'odre lexicographique que u2'. Par exemple u1 = xbegyak est plus petit que u2 = xbygeak, car u1' = eyaxbgk est plus petit,pour l'ordre lexicographique , que u2' = yeaxbgk. Nous appellerons cette relation d'ordre “voyelles-consonnes”.
Ecrire une fonction réalisant la comparaison de deux chaines de caractères suivant la relation “voyelles-consonnes”.Attention :au sortir de la fonction ,les chaines de caractères doivent etre telles qu' elles étaient au départ de la fonction.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 char *range(const char *s){ char * tmp; size_t n = strlen(s); int i; int nb = 0; for(i=0; i<n; i++) { tmp[nb] = s[i]; nb++; } for(i=0; i<n; i++) { tmp[nb] = s[i]; nb++; } tmp[nb] = '\0'; return tmp; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int cmpVoyellesConsonnes(const char *s1, const char *s2) { char *t1,*t2; t1 = range(s1); t2 = range(s2); return cmpLexico(t1,t2); }
Exercice 4
Soit un flot texte, ouvert en lecture , dont nous supposerons qu'il ne contient que des lignes composées de consonnes et de voyelles (pas de chiffres,espacements,ponctuations,etc..).Ecrire une fonction
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 int triFlots(FILE *flotLecture, FILE *flotEcriture, int (*cmp)(const char *s1, const char *s2))prenant un tel flot en paramètre ,avec un autre flot texte ,ouvert en écriture ,et qui met dans le second toutes les lignes du premier, triées par l'ordre donné par la fonction désignée par cmp.Vous n'avez pas le droit de faire le tri directement : vous devez utiliser un tas ,dans lequel vous mettrez les lignes du flot en lecture,puis vous en retirerez les éléments un par un pour pour les mettre dans le flot en écriture.La fonction retourne 0 si tout se passe bien ,un code d'erreur sinon. N'oubliez pas de libérer toutes les ressources intermédiaires quand vous n'en avez plus besoin.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 int triFlots(FILE *flotLecture, FILE *flotEcriture, int (*cmp)(const char *s1, const char *s2)) { char ligne[256]; char *mot; char *sep = " "; Heap *h; char *res; if(flotLecture != NULL) { char *lu = fgets(ligne, sizeof ligne, flotLecture); mot = strtok(lu,sep); while(lu != NULL) { if(newHeap(&h,cmp) { fprintf(stderr,"erreur\n"); return 1; } do { if(addToHeap(h,mot)) { fprintf(stderr,"erreur\n"); return 1; } if(removeSmallestFromHeap(h,res)) { fprintf(stderr,"erreur\n"); return 1; } fprintf(flotEcriture,"%s",res); mot = strtok(NULL,sep); }while(mot != NULL); } } freeHeap(&h); return 0; }
Voici mes commentaires:
Cela m'étonnerait que tu puisses utiliser strcmp. On te dit d'utiliser les mêmes conventions de retour que strcmp mais cela ne veut pas dire t'en servir...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int cmpLexico(const char *s1, const char *s2) { return strcmp(s1,s2); }
Je ne comprends pas pourquoi tu n'as pas simplement fait ceci (vu que t'étais flemmard pour le premier, pourquoi pas pour le 2ème):
Code : Sélectionner tout - Visualiser dans une fenêtre à part int cmpInvLexico(const char *s1,const char *s2)
Mais en regardant ton code...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 { return strcmp(s2,s1); }
Heureusement que tmp1 est bien alloué... (idem pour tmp2 d'ailleurs)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 char *tmp1,*tmp2; for(i=0; i<l1; i++) tmp1[i] = s1[l1-1-i];
Et là je ne comprends pas... Pourquoi copier les chaines et ensuite les envoyer à cmpLexico? Pourquoi ne pas juste utiliser:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 return (cmpLexico(tmp1,tmp2));
Remarque: si tu fais à la main cmpLexico, tu as entièrement le droit de l'utiliser dans la programmation de cmpInvLexico...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 int cmpInvLexico(const char *s1,const char *s2) { return cmpLexico(s2,s1); }
Exercice 2Pourquoi faire compliqué?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 int cmpMilitaire(const char *s1, const char *s2) { size_t l1,l2; l1 = strlen(s1); l2 = strlen(s2); if(l1 == l2) return 0; else return l1<l2 ? -1 : 1 ; }
Et ici:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 //cmpMilitaire rend 0 si les chaîne ont le même ordre // <0 si s1 a un ordre plus petit //>0 si s1 a un ordre plus grand int cmpMilitaire(const char *s1, const char *s2) { return strlen(s1)-strlen(s2); }
L'ordre de tes arguments te semblent-ils vraiment correct?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int cmpInvMilitaire(const char *s1, const char *s2) { return cmpMilitaire(s1,s2)); }
Voilà sur les 2 premiers... Mais je ne suis pas la pour corriger... Peut-être que quelqu'un d'autre regardera la suite... ou alors peut-etre que demain...
Jc
Bon aller, c'est le 23 et bientôt Noël... Continuons la correction,
Exercice 3)
Pour la nième, est-ce que tu as alloué de la place pour tmp?????
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 char *range(const char *s){ char * tmp; size_t n = strlen(s); int i; int nb = 0; for(i=0; i<n; i++) { tmp[nb] = s[i]; nb++; } for(i=0; i<n; i++) { tmp[nb] = s[i]; nb++; } tmp[nb] = '\0'; return tmp; }![]()
Ensuite, tes deux boucles devraient peut-être avoir un test dedans, non? Dans la première je verrais bien un
et dans le deuxième
Code : Sélectionner tout - Visualiser dans une fenêtre à part if( Voyelle(s[i]))...
Code : Sélectionner tout - Visualiser dans une fenêtre à part if (Consonne(s[i]))
Par contre ta fonction cmpVoyellesConsonnes est correcte sauf que tu as une fuite de mémoire, ce qui est considérée comme grave.
4)
Cette solution est carrément fausse puisque tu n'as pas vraiment lu le sujet...
On te dit qu'il n'y a pas d'espaces dans les lignes alors pourquoi faire:
De plus, je te déconseille l'utilisation de la fonction strtok...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 mot = strtok(lu,sep);
Ensuite, ce code n'est pas compilable,
De plus l'algorithme de cette solution est fausse, logiquement, tu lirais tous les mots et tu les mettrais dans le tas et ensuite tu les récupères pour les écrire... Ce n'est pas ce que tu fais... (d'ailleurs, si tu regardes bien c'est ce qu'il y a dans le sujet, pourquoi ne pas suivre le sujet?)
Code : Sélectionner tout - Visualiser dans une fenêtre à part if(newHeap(&h,cmp)
JcEnvoyé par du sujet que tu n'as pas suivi
Merci fearyourself pour ces éléments de réponse.
J'ai réécrit tous les codes:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 int cmpLexico(const char *s1, const char *s2) { while(*s1 == *s2) { if(*s1 == '\0') return 0; s1++; s2++; } return *s1<*s2 ? -1 : 1; } int cmpInvLexico(const char *s1, const char *s2) { return cmpLexico(s2,s1); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 int cmpMilitaire(const char *s1, const char *s2) { return strlen(s1)-strlen(s2); } int cmpInvMilitaire(const char *s1, const char *s2) { return cmpMilitaire(s2,s1); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 int Voyelle(char c) { if(c == 'a' || c== 'e' || c == 'i' || c == 'o' || c== 'u' || c == 'y') return 0; return 1; } int Consonne(char c) { if(Voyelle(c) == 0) return 1; return 0; } char *change(const char *s) { char *tmp; size_t n = strlen(s); int i,nb=0; tmp = (char*)malloc(n+1); if(tmp == NULL) return NULL; for(i=0; i<n; i++) { if(Voyelle(s[i])) { tmp[nb] = s[i]; nb++; } } for(i=0; i<n; i++) { if(Consonne(s[i])) { tmp[nb] = s[i]; nb++; } } tmp[nb] = '\0'; return tmp; } int VoyellesConsonnes(const char *s1, const char *s2) { char *t1 = change(s1); char *t2 = change(s2); return cmpLexico(t1,t2); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 int triFlots(FILE *flotLecture, FILE *flotEcriture, int (*cmp)(const char *s1, const char *s2)) { char ligne[256]; char *mot; Heap *h; char *res; if(flotLecture != NULL) { if(newHeap(&h,cmp)) { fprintf(stderr,"erreur\n"); return 1; } char *lu = fgets(ligne, sizeof ligne, flotLecture); while(lu != NULL) { if(addToHeap(h,lu)) { fprintf(stderr,"erreur\n"); return 1; } } if(removeSmallestFromHeap(h,res)) { fprintf(stderr,"erreur\n"); return 1; } fprintf(flotEcriture,"%s",res); freeHeap(&h); } return 0; }
A la fin, on y arrivera...
Si tu écris cette fonction comme ceci:
Est-ce que ça te semble logique ici?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int Voyelle(char c) { if(c == 'a' || c== 'e' || c == 'i' || c == 'o' || c== 'u' || c == 'y') return 0; return 1; }
Dans le sujet, on te demande de libérer les ressources qui ne seront plus utilisées, est-ce que tu penses que le fais ici?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 if(Voyelle(s[i])) { tmp[nb] = s[i]; nb++; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 int VoyellesConsonnes(const char *s1, const char *s2) { char *t1 = change(s1); char *t2 = change(s2); return cmpLexico(t1,t2); }
Est-ce que tu crois que ici tu ajoutes vraiment toutes les lignes au tas? J'ai l'impression que tu prends la première ligne et que tu fais une boucle infinie...
Et enfin, est-ce qu'ici tu as l'impression que tu vas ressortir toutes les lignes du tas sans une boucle mais juste un if?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 char *lu = fgets(ligne, sizeof ligne, flotLecture); while(lu != NULL) { if(addToHeap(h,lu)) { fprintf(stderr,"erreur\n"); return 1; } }
Jc
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 if(removeSmallestFromHeap(h,res)) { fprintf(stderr,"erreur\n"); return 1; }
Je ne vois pas ou est le problème ?Si tu écris cette fonction comme ceci:
Est-ce que ça te semble logique ici?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int Voyelle(char c) { if(c == 'a' || c== 'e' || c == 'i' || c == 'o' || c== 'u' || c == 'y') return 0; return 1; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 if(Voyelle(s[i])) { tmp[nb] = s[i]; nb++; }
Je vérifies que la lettre rencontrée est une voyelle ,si c'est le cas ,j'affecte cette lettre à tmp[nb] et j'incrémente le nb élément de tmp.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 int triFlots(FILE *flotLecture, FILE *flotEcriture, int (*cmp)(const char *s1, const char *s2)) { char ligne[256]; char *mot; Heap *h; char *res; if(flotLecture != NULL) { if(newHeap(&h,cmp)) { fprintf(stderr,"erreur\n"); return 1; } while(fgets(ligne, sizeof ligne, flotLecture) != NULL) { if(addToHeap(h,ligne)) { fprintf(stderr,"erreur\n"); return 1; } } while(h != NULL) { if(removeSmallestFromHeap(h,res)) { fprintf(stderr,"erreur\n"); return 1; } fprintf(flotEcriture,"%s",res); } freeHeap(&h); } return 0; }
Partager