aiee dsldsl dsldsl
je l'avais mis pour les aeroports et il a du mal a rentrer dans mon cerveau celui la donc je l'ai oublié ici encore...
bon maintenant il devrait rester
merci encore et dsl pour le temps perdu
aiee dsldsl dsldsl
je l'avais mis pour les aeroports et il a du mal a rentrer dans mon cerveau celui la donc je l'ai oublié ici encore...
bon maintenant il devrait rester
merci encore et dsl pour le temps perdu
juste une précision sur la fonction que tu me proposes ... :
je vois pas trop l'objectif de la partie /*purge*/...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 else { /* purge */ int c; while ((c = fgetc(fp)) != '\n' && c != EOF) { } }
je serai d'avis de mettre quelquechose dans le while, non ??
en fait voila comment je comprends ton code en francais...:
bon peut etre je saisis pas quelquechose, je voudrais juste comprendre l'objectif de cette partie
- je cherche le caractère \n dans la ligne lue, et je fais pointer p dessus.
- si p est != de NULL ( ce qui sous-entend qu'un \n a été trouvé) alors je remplace ce \n par 0.
- SINON, ( pas de \n trouvé), tant que chaque caractère est != de \n et de la fin de fichier...
Si tu ne trouves pas le \n dans ce qui est lue, c'est que tout ce qui a ete saisie n'a pas ete lu, il reste des caracteres dans le flux stdin. Le but de la purge est donc de supprimmer ces caracteres restant.Envoyé par BnY
Il n'y a rien a faire dans la partie "commande" du while puisque la fonction fgetc() dans la partie "condition" du while consomme deja ces caracteres restants.
Tout celà était expliqué en long en large et en travers dans les articles sur mon site dont je t'ai passé les liens il y a quelques temps...Envoyé par BnY
C'est ce mécanisme de purge qui fait que tout appel suivant de fgets() est stable (blocant).
Pas de Wi-Fi à la maison : CPL
re
petit problème de pointeurs avec les fonctions... j' ai cherché dans mon livre et sur ton site ED et j'ai pas trouvé ce que je cherchais...:
voici le code sur lequel je travaille:
je cherche avec la fonction login à retourner une valeur selon le profile dans le main et en meme temps à passer par référence les valeurs des pointeurs ptr et ptr2... je pensais qu'en les passant en arguments dans la fonction login,je recupererai leurs valeurs dans le main... mais apparement non ... où est mon erreur svp??
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 #include<stdio.h> #include<stdlib.h> #include<string.h> void clean(char*,FILE*); void testFGETS(char*); int testPROFILE(char*); void sauterdeuxlignes(char*,FILE*); int login(char*,char*); int main(void) { char *pt=NULL,*pt2=NULL; login(pt,pt2); printf("\npt et pt2: %s et %s",pt,pt2); } /*fonction login*/ int login (char *ptr,char *ptr2) { char chaine[200],login[200],pass[200]; FILE*flotuti; char *ptr3; int profile,i=0; while(i<3) { printf("\nentrer login"); fgets(login,sizeof login,stdin); clean(login,stdin); printf("\nentrer pass"); fgets(pass,sizeof pass,stdin); clean(pass,stdin); flotuti=fopen("ficUtilisateurs.txt","r"); if (flotuti==NULL) { printf("\nerreur ouverture"); } sauterdeuxlignes(chaine,flotuti); while((ptr3=fgets(chaine,sizeof chaine,flotuti))!=NULL) { if(ptr3==NULL) { printf("\nerreur ptr fgets nul"); } clean(chaine,flotuti); ptr=strstr(chaine,login); if (ptr==NULL) { continue; } else { ptr2=strstr(chaine,pass); if (ptr2!=NULL) { printf("\nidentifiants valides%s",ptr); break; } } } profile=testPROFILE(chaine); if ((ptr!=NULL)&&(ptr2!=NULL)) { printf("\ntout va bien"); i=4; } else { printf("\nerreur d'identifiants"); i++; } } if(i==3) { printf("\ntrois erreurs, fin du programme"); } fclose(flotuti); return profile; } /* fonctions annexes*/ static void clean (char *s, FILE *fp) { /* search ... */ char *p = strchr (s, '\n'); if (p != NULL) { /* ... and kill */ *p = 0; } else { /* purge */ int c; while ((c = fgetc(fp)) != '\n' && c != EOF) { } } } void testFGETS(char* string) { int i, retourALaLigne = 0; for (i = 0; string[i] != '\0'; i++) { if (string[i] == '\n') { printf("\nLa chaine contient un retour a la ligne."); retourALaLigne = 1; } } if (retourALaLigne == 0) { printf("\nLa chaine ne contient pas de retour a la ligne."); } } int testPROFILE(char* string) { int profile; if(strstr(string,"chefregulateur")!=NULL) { profile=1; } if(strstr(string,"regulateur")!=NULL) { profile=2; } if(strstr(string,"securiteinfo")!=NULL) { profile=3; } return profile; } void sauterdeuxlignes(char* chaine,FILE *flot) { fgets(chaine,sizeof chaine,flot); clean(chaine,flot); fgets(chaine,sizeof chaine,flot); clean(chaine,flot); }
Je pense que tu écris trop de code à la fois sans le tester. L'algorithme de login est très mal fait puisqueEnvoyé par BnY2 approches :
- tu ouvres le fichier à chaque tour
- tu continues même si le fichier est absent (ce qui m'a valu un beau crash, merci...)
- tu le fermes une fois en quittant la boucle (on ne sait pas comment quitter cette boucle, d'ailleurs)...
Exemple concrêt : La lecture d'un fichier.
- Soit tu travailles sur l'algo à-priori, c'est à dire que tu l'écris clairement sur le 'papier', et tu le fais tourner à la main en imaginant ce qui se passe dans les différents cas (au passage, excellent exercice de gymnastique mentale, mais risque d'erreur si, comme moi, on est pas un athlète de la réflexion)
- Soit tu fais du codage incrémental, c'est à dire que en gros tu écris une (ou quelques) ligne de code, et tu la testes au fur et à mesure. Une fois que c'est validé, tu passes à la suite. C'est la méthode que j'utilise, et c'est celle qui est recommandée par les méthodes dites 'agiles' (eXtrem Programming etc.).
Première étape : Ouverture et fermeture.
Si je commence 'bille en tête', je vais faire, par exemple ceci :
Ca parait simple et correct, mais si je teste ce code, il fonctionnera sans problème si le fichier existe, mais invoquera un comportement indéfini (Undefined Behaviour ou UB) si le fichier n'existe pas. Pourquoi ? parce que passer NULL à fclose() invoque un UB.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 #include <stdio.h> int main (void) { FILE *fp = fopen("fichier.txt", "r"); fclose(fp); return 0; }
Donc, ce code est mal écrit. C'est pas la peine d'aller plus loin avant correction.
1 ère correction : tester la valeur avant de l'utiliser :
Facile :
C'est pas plus compliqué que çà.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #include <stdio.h> int main (void) { FILE *fp = fopen("fichier.txt", "r"); if (fp != NULL) { fclose(fp); } return 0; }
On peut aider l'utilisateur en lui indiquand la cause du problème avec perror(). Comme on utilise 2 fois le nom du fichier, on le 'factorise (macro, variable en lecture seule, peu importe) :
ce qui donne
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 #include <stdio.h> int main (void) { char const fname[] = "fichier.txt"; FILE *fp = fopen(fname, "r"); if (fp != NULL) { fclose(fp); } else { perror(fname); } return 0; }
si le fichier n'est pas là.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2fichier.txt: No such file or directory
Ensuite, on peut passer à la lecture. La aussi, il faut résister à tout :
fichier vide, chaine trop longue etc. J'ajoute un peu de trace pour expliquer la cause de l'arrêt de la lecture :
Test avec un fichier vide :
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 #include <stdio.h> int main (void) { char const fname[] = "fichier.txt"; FILE *fp = fopen(fname, "r"); if (fp != NULL) { char line [32]; while (fgets (line, sizeof line, fp) != NULL) { /* debug */ puts(line); } if (feof(fp)) { puts("<EOF>"); } if (ferror(fp)) { perror(fname); } fclose(fp); } else { perror(fname); } return 0; }
Test avec un fichier de quelques lignes... (accents volontairement retirés pour des raisons bien connues de compatibilité)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2<EOF>
ce qui donne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5Maitre corbeau, sur un arbre perche, Tenait en son bec un fromage. Maitre renard par l'odeur alleche , Lui tint a peu pres ce langage :
Se rappeler que puts() ajoute un '\n' à la fin du texte. On peut donc constater que les lignes on été lues 'en deux fois' (rien n'a été perdu). Ca signifie tout simplement que le tableau de char 'line' est
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 Maitre corbeau, sur un arbre pe rche, Tenait en son bec un fromage. Maitre renard par l'odeur allec he , Lui tint a peu pres ce langage : <EOF>
trop petit. On voit aussi que lorsque la ligne est lue entièrement, le '\n' est lu aussi (avec le '\n' du puts(), ça provoque une ligne blanche)
Correction : Il y a plusieurs corrections possibles
- réassembler les lignes incomplètes (un peu compliqué)
- utliser une ligne de taille variable (un peu compliqué, msai c'est ce que je fais dans la vraie vie)
- ignorer la suite (la fameuse purge de ma fonction clean()) : un peu brutal et peu respectueux pour Mr de la Fontaine...
- agrandir le tableau : semble être le plus raisonnable.
Ce qui donne maintenant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 <...> if (fp != NULL) { char line [64]; while (fgets (line, sizeof line, fp) != NULL) { <...>
Ce qui parait plus convenable.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Maitre corbeau, sur un arbre perche, Tenait en son bec un fromage. Maitre renard par l'odeur alleche , Lui tint a peu pres ce langage : <EOF>
Il reste maintenant à se débarasser proprement des '\n' (si on le souhaite), et c'est là que la fonction clean() trouve son utiliité :
Ce qui donne
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 #include <stdio.h> #include <string.h> static void clean (char *s, FILE *fp) { /* search ... */ char *p = strchr (s, '\n'); if (p != NULL) { /* ... and kill */ *p = 0; } else { /* purge */ int c; while ((c = fgetc(fp)) != '\n' && c != EOF) { } } } int main (void) { char const fname[] = "fichier.txt"; FILE *fp = fopen(fname, "r"); if (fp != NULL) { char line [64]; while (fgets (line, sizeof line, fp) != NULL) { clean (line, fp); /* debug */ puts(line); } if (feof(fp)) { puts("<EOF>"); } if (ferror(fp)) { perror(fname); } fclose(fp); } else { perror(fname); } return 0; }
Et voilà. Je recommande de faire comme ça tout le temps. Pas à pas, étape par étape, en consolidant l'étape courante avant de passer à la suivante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Maitre corbeau, sur un arbre perche, Tenait en son bec un fromage. Maitre renard par l'odeur alleche , Lui tint a peu pres ce langage : <EOF>
Ca parait plus lent, mais c'est tellement plus solide !
Pas de Wi-Fi à la maison : CPL
oki je vais appliquer cette méthode
le truc c'est que moi je testais le tout à coup de printf un peu partout pour voir si les variables prenaient la valeur que je voulais etc... brutal mais bon dans les cas ou le fichier est la et tout ( oui c'est sur dans les cas favorables lol ) la fonction login marche tres bien, y avait juste ce problème de pointeur...
bon je vais quand meme ecoutes tes sages conseils et mettre un peu d'ordre et de securité la dedans...
sinon en attendant j'ai un petit code qui me permet d'afficher la date et l'heure et je sais pas pourquoi il bugg...:
est ce qu'il y a des tests d'erreurs comme ceux prescrits plus haut avec les fichiers et flots... ??
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 #include <stdio.h> #include <time.h> void main() { time_t tim; char chainedate[1024]; struct tm *tmst; tmst=localtime(&tim); strftime(chainedate,128,"%Y/%m/%d\t\t%H:%M:%S\t\t",tmst); printf("\n%s",chainedate); }
si non, tu sais ou je fais une erreur ??
merci
Il faut commencer par lire la doc et ton livre de C. La date système ne tombe pas du ciel comme ça. Il faut appeler time()...Envoyé par BnY
Et puis main() retourne int. Toujours.
http://emmanuel-delahaye.developpez....s.htm#typemain
Pas de Wi-Fi à la maison : CPL
oki merci... meme en lisant mon livre C a ce sujet j'avais pas bien compris qu'il était nécessaire d'appeler time()...
m'enfin ca te donne le niveau de ma super prof d'info qui nous a gentillement donné ce code qui n'est pas complet sans nous dire qu'il était pas complet... !! lol
vu comme ca, ca devrait aller mieux
pour ce qui concerne strstr, elle est très bien cette fonction mais quand je m'en sers pour chercher le login dans la ligne du fichier elle retourne un pointeur vers toute la ligne... c'est bizarre vu que normalement elle devrait retourner un pointeur vers la sous-chaine seulement... par exemple la partie de code suivante:
m'affiche:
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 while((ptr3=fgets(chaine,sizeof chaine,fputil))!=NULL) { if(ptr3==NULL) { printf("\nerreur ptr fgets nul"); } clean(chaine,fputil); ptr=strstr(chaine,login); if (ptr==NULL) { continue; } else { ptr2=strstr(chaine,pass); if (ptr2!=NULL) { printf("\nidentifiants valides%s",ptr); break; } } } if ((ptr!=NULL)&&(ptr2!=NULL)) { printf("\n%s et %s",ptr,ptr2); }
c'est bien joli mais je voudrais que ces pointeurs pointent seulement vers les noms de debut de chaine... :durand durand28 regulateur
durand28 regulateur
ce qui afficherait ceci:
bon je me doute bien que je ne peux pas transformer directement la chaine pointée à la sortie de strstr mais je ne sais pas trop comment virer la fin de la chaine... une fois que j'ai les pointeurs ptr et ptr2 qui me donnent toute leur ligne...durand
durand28
quelqu'un a une idée qui pourrait m'aider ??
Cette fonction ne sert qu'à vérifier la présence d'une sous-chaine sans une autre, c'est tout. Elle y est ou elle n'y est pas. Point. Ici, ça te sert à repérer la ligne qui t'interesse. Ensuite c'est à toi d'analyser la ligne pour en extraire d'autres informations si nécessaire.Envoyé par BnY
Mais une fois de plus, tu sautes sur le code au lieu de commencer par écrire l'algo...
Pas de Wi-Fi à la maison : CPL
ben en fait elle rtourne aussi un pointeur vers cette chaine...et je cherchais déjà a ecrire l'algo qui me permettrait d'utiliser ces pointeurs a ma guise... mais bon comme tu dis je vais essayer de travailler sur la ligne et non d'utiliser le pointeur retourné ...
enfin en ce qui concerne l'algo, je cherche pas vraiment a ecrire l'algo, c'est vrai, mais je cherche la methode que je vais utiliser pour faire ce que jveux, puis je la traduis en C... je n'ai jamais appris a ecrire de l'algo donc je fais avec les moyens du bord ^^
je pense que je suis assez mal organisé dans mes reflexions et je vais peut etre pas assez au bout du raisonnement et donc de "l'algo" qui traduit tout le code...
bon merci pour le conseil je retourne dessus
Il pointe sur le début du mot trouvé, c'est tout. Si on le fait avancer de la longeur du mot :Envoyé par BnY
il pointe juste après le mot. Ca peut être bien de commencer une analyse à partir de là...Je ne sais pas ce que tu veux faire...
Code : Sélectionner tout - Visualiser dans une fenêtre à part p += strlen("aiguille");
L'algo, c'est de la pensée organisée.enfin en ce qui concerne l'algo, je cherche pas vraiment a ecrire l'algo,
[/code]
C'est un tord.
[code]
c'est vrai, mais je cherche la methode que je vais utiliser pour faire ce que jveux, puis je la traduis en C... je n'ai jamais appris a ecrire de l'algo donc je fais avec les moyens du bord ^^
Maintenant que tu le sais, tu sais quoi faire... Commence par décrire le fonctionnement atendu avec des phrases, des conditions....je pense que je suis assez mal organisé dans mes reflexions et je vais peut etre pas assez au bout du raisonnement et donc de "l'algo" qui traduit tout le code...
Contrairement à ce qu'on croit souvent, l'informatique c'est surtout du français[1] et de la logique. L'aspect mathématique est faible (un peu d'arithmétique entière, et d'algèbre de Boole rien de compliqué).
-----------------------
[1] mettre la langue du codeur...
Pas de Wi-Fi à la maison : CPL
Algorithme : Le langage le plus performant, car c'est celui qui "marche" le plus souvent. Il n'est malheureusement pas implanté sur les machines.
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager