[C] Passage d'une structure en paramètre
Résolu/Fermé
ilan27
Messages postés
394
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
15 juin 2009
-
16 janv. 2008 à 19:21
kilian Messages postés 8732 Date d'inscription vendredi 19 septembre 2003 Statut Non membre Dernière intervention 5 février 2025 - 17 janv. 2008 à 00:59
kilian Messages postés 8732 Date d'inscription vendredi 19 septembre 2003 Statut Non membre Dernière intervention 5 février 2025 - 17 janv. 2008 à 00:59
A voir également:
- [C] Passage d'une structure en paramètre
- Netflix paramètre compte - Guide
- Remettre parametre usine pc - Guide
- Passage qwerty azerty - Guide
- Parametre windows - Guide
- Changer parametre dns - Guide
10 réponses
Pacorabanix
Messages postés
3248
Date d'inscription
jeudi 23 août 2007
Statut
Membre
Dernière intervention
19 mai 2013
662
16 janv. 2008 à 20:52
16 janv. 2008 à 20:52
Bonjour,
je remarque plusieurs choses qui ne jouent pas .
char *ligne=(char *)malloc(60);
le (char *) est inutile et dangereux. Il ne faut pas "caster" (convertir) le retour de malloc.
ensuite concernant ton affectation qui ne compile pas :
t[i]={numligne, nomEtiquette(ligne)};
je ne crois pas qu'on puisse faire comme cela (sauf à la déclaration des variables ). par contre tu peux faire t[i].adresse = numligne
et pour la chaine de caractere faire une copie de chaine (voir https://c.developpez.com/faq/?page=Les-chaines-de-caracteres#STRINGS_string_init )
ensuite pour les struct etc... je m'embrouille toujours :) voir ici https://c.developpez.com/faq/#KEYWORD_typedef_struct pour utiliser typedef et struct.
je remarque plusieurs choses qui ne jouent pas .
char *ligne=(char *)malloc(60);
le (char *) est inutile et dangereux. Il ne faut pas "caster" (convertir) le retour de malloc.
ensuite concernant ton affectation qui ne compile pas :
t[i]={numligne, nomEtiquette(ligne)};
je ne crois pas qu'on puisse faire comme cela (sauf à la déclaration des variables ). par contre tu peux faire t[i].adresse = numligne
et pour la chaine de caractere faire une copie de chaine (voir https://c.developpez.com/faq/?page=Les-chaines-de-caracteres#STRINGS_string_init )
ensuite pour les struct etc... je m'embrouille toujours :) voir ici https://c.developpez.com/faq/#KEYWORD_typedef_struct pour utiliser typedef et struct.
ilan27
Messages postés
394
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
15 juin 2009
36
16 janv. 2008 à 21:49
16 janv. 2008 à 21:49
Merci pour vos réponses!
En effet, j'ai déjà essayé :
strcpy(t[i].nom, nomEtiquette(ligne));
t[i].adresse=numligne;
Mais le résultat est le même (ça contredit vraiment ce que j'avais appris, ou du moins je ne vois pas de 'piège'...)
En ce qui concerne le cast, j'ai appris qu'il n'était pas nécessaire, mais qu'il était préférable de le mettre, alors tant qu'à faire...
J'ai regardé les liens, notamment sur les struct, mais les tableaux de struct ne sont pas abordés. J'ai donc essayé un typedef, mais ça n'a pas l'air de marcher.
Code::Blocks a vraiment un sale caractère! :p
Si vous détectez d'autres lueurs de solutions... ;)
Merci!
En effet, j'ai déjà essayé :
strcpy(t[i].nom, nomEtiquette(ligne));
t[i].adresse=numligne;
Mais le résultat est le même (ça contredit vraiment ce que j'avais appris, ou du moins je ne vois pas de 'piège'...)
En ce qui concerne le cast, j'ai appris qu'il n'était pas nécessaire, mais qu'il était préférable de le mettre, alors tant qu'à faire...
J'ai regardé les liens, notamment sur les struct, mais les tableaux de struct ne sont pas abordés. J'ai donc essayé un typedef, mais ça n'a pas l'air de marcher.
Code::Blocks a vraiment un sale caractère! :p
Si vous détectez d'autres lueurs de solutions... ;)
Merci!
kilian
Messages postés
8732
Date d'inscription
vendredi 19 septembre 2003
Statut
Non membre
Dernière intervention
5 février 2025
1 526
16 janv. 2008 à 22:10
16 janv. 2008 à 22:10
C'est bien comme ça qu'il faut faire:
Le problème c'est qu'il considère que ton type struct Etiquette n'est pas défini.
Tu n'aurais pas déclaré ton type struct Etiquette à l'intérieur d'une fonction et non pas de manière globale?
Sinon, il faudrait que tu nous mettes la source complète...
strcpy(t[i].nom, nomEtiquette(ligne)); t[i].adresse=numligne;
Le problème c'est qu'il considère que ton type struct Etiquette n'est pas défini.
Tu n'aurais pas déclaré ton type struct Etiquette à l'intérieur d'une fonction et non pas de manière globale?
Sinon, il faudrait que tu nous mettes la source complète...
ilan27
Messages postés
394
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
15 juin 2009
36
16 janv. 2008 à 22:19
16 janv. 2008 à 22:19
Merci pour ta réponse.
J'ai déclaré "struct Etiquette" et le tableau de struct Etiquette dans le main, et c'est dans le main que j'appelle la fonction dans laquelle il y a le problème. (Je passe le tableau en paramètre). Je ne vois pas ce qui pourrais être plus global... Tu penses qu'il y a une erreur à ce niveau?
Y a-t-il (on sait jamais) une bibliothèque particulière aux struct?
J'ai déclaré "struct Etiquette" et le tableau de struct Etiquette dans le main, et c'est dans le main que j'appelle la fonction dans laquelle il y a le problème. (Je passe le tableau en paramètre). Je ne vois pas ce qui pourrais être plus global... Tu penses qu'il y a une erreur à ce niveau?
Y a-t-il (on sait jamais) une bibliothèque particulière aux struct?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
kilian
Messages postés
8732
Date d'inscription
vendredi 19 septembre 2003
Statut
Non membre
Dernière intervention
5 février 2025
1 526
16 janv. 2008 à 22:26
16 janv. 2008 à 22:26
Oui il y a une erreur à ce niveau :-)
Si tu déclares un type dans une fonction (appelons là fonction1), la portée de ce type ne sera visible que dans cette fonction1, sa définition ne sera pas visible ailleurs même dans une autre fonction (appelons là fonction2) appelée dans cette fonction1. Car la définition de fonction2 se fait ailleurs, dans un endroit ou la définition de ton type n'est pas visible.
Il faut que tu rendes global la définition de ta structure, que tu la définises en dehors de toute fonction. Et juste le type, pas la variable.
Si tu déclares un type dans une fonction (appelons là fonction1), la portée de ce type ne sera visible que dans cette fonction1, sa définition ne sera pas visible ailleurs même dans une autre fonction (appelons là fonction2) appelée dans cette fonction1. Car la définition de fonction2 se fait ailleurs, dans un endroit ou la définition de ton type n'est pas visible.
Il faut que tu rendes global la définition de ta structure, que tu la définises en dehors de toute fonction. Et juste le type, pas la variable.
ilan27
Messages postés
394
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
15 juin 2009
36
16 janv. 2008 à 22:39
16 janv. 2008 à 22:39
J'ai essayé d'écrire
struct Etiquette{
int adresse;
char nom[20];
};
struct Etiquette t[20];
avant le main.
Du coup, je retire les paramètres "struct Etiquette * " dans l'appel et la définission de la fonction à problème...etc
Normalement elle devrait etre globale cette structure, et t aussi.
Et il 'ose' me mettre
" 't' undeclared, first use in this function"
Each undeclared identifier is reported only once for each function it appears in" (!!)
Je vous mets le code:
FICHIER MAIN.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utile.h"
int main()
{
int code;
int i=0;
FILE *src=fopen("essai.txt", "r");
FILE *cpy=fopen("copy.txt", "w");
//On ne souhaite que le lire: "r". Ici, src ---> nomdufichier
char *ligne=(char*)malloc(60);
for(i=0; i<60; i++) ligne[i]='\0';
//On va récupérer d'éventuelles étiquettes
struct Etiquette{
int adresse;
char nom[20];
};
struct Etiquette t[20];
recupereEtiquettes(src, t, 20);
fgets(ligne, 60, src);
code=traduction(ligne, t);
//t est nécessaire, car la traduction va l'utiliser pour associer les adresses
fprintf(cpy, "%d\n", code);
free(ligne);
fclose(cpy);
fclose(src);
return 0;
}
ET UTILE.C: (J'ai enlevé une partie qui n'avait rien à voir)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <math.h>
int isEtiquette(char c[]){
int i=0;
for(i; c[i]; i++){
if(c[i]==':') return 0;
}
return 1;
}
char * nomEtiquette(char *s){
int i=0;
char *res=(char *)malloc(20);
for(i; *(s+i)!=':'; i++){
*(res+i)=*(s+i);
}
return res;
}
void recupereEtiquettes(FILE * source, struct Etiquette * t,int taille){
int i=0, numligne=0;
char *ligne=(char *)malloc(60);
//temporaire
do{
fgets(ligne, 60, source);
if(isEtiquette(ligne)){
//struct Etiquette t[i];
//t[i]={0, ""};
//t[i]={numligne, nomEtiquette(ligne)};
strcpy(t[i].nom, nomEtiquette(ligne)); // -------------------------------------ICI-----------------------------
t[i].adresse=numligne;
i+=1;
}
numligne+=(sizeof(int));
}while(ligne!=NULL && i<taille);
if(i>=taille) printf("Trop d'étiquettes à stocker!\n");
}
struct Etiquette{
int adresse;
char nom[20];
};
struct Etiquette t[20];
avant le main.
Du coup, je retire les paramètres "struct Etiquette * " dans l'appel et la définission de la fonction à problème...etc
Normalement elle devrait etre globale cette structure, et t aussi.
Et il 'ose' me mettre
" 't' undeclared, first use in this function"
Each undeclared identifier is reported only once for each function it appears in" (!!)
Je vous mets le code:
FICHIER MAIN.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utile.h"
int main()
{
int code;
int i=0;
FILE *src=fopen("essai.txt", "r");
FILE *cpy=fopen("copy.txt", "w");
//On ne souhaite que le lire: "r". Ici, src ---> nomdufichier
char *ligne=(char*)malloc(60);
for(i=0; i<60; i++) ligne[i]='\0';
//On va récupérer d'éventuelles étiquettes
struct Etiquette{
int adresse;
char nom[20];
};
struct Etiquette t[20];
recupereEtiquettes(src, t, 20);
fgets(ligne, 60, src);
code=traduction(ligne, t);
//t est nécessaire, car la traduction va l'utiliser pour associer les adresses
fprintf(cpy, "%d\n", code);
free(ligne);
fclose(cpy);
fclose(src);
return 0;
}
ET UTILE.C: (J'ai enlevé une partie qui n'avait rien à voir)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <math.h>
int isEtiquette(char c[]){
int i=0;
for(i; c[i]; i++){
if(c[i]==':') return 0;
}
return 1;
}
char * nomEtiquette(char *s){
int i=0;
char *res=(char *)malloc(20);
for(i; *(s+i)!=':'; i++){
*(res+i)=*(s+i);
}
return res;
}
void recupereEtiquettes(FILE * source, struct Etiquette * t,int taille){
int i=0, numligne=0;
char *ligne=(char *)malloc(60);
//temporaire
do{
fgets(ligne, 60, source);
if(isEtiquette(ligne)){
//struct Etiquette t[i];
//t[i]={0, ""};
//t[i]={numligne, nomEtiquette(ligne)};
strcpy(t[i].nom, nomEtiquette(ligne)); // -------------------------------------ICI-----------------------------
t[i].adresse=numligne;
i+=1;
}
numligne+=(sizeof(int));
}while(ligne!=NULL && i<taille);
if(i>=taille) printf("Trop d'étiquettes à stocker!\n");
}
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
16 janv. 2008 à 22:45
16 janv. 2008 à 22:45
Salut,
Je constate dans ton code plusieurs erreurs.
Tout d'abord pourquoi faire de l'allocation dynamique alors que tu connais ta longueur à la déclaration ? Un simple char variable[50] suffirait.
t[i]={....} que tu as mis en commentaire, ne peut pas marcher sauf à la déclaration.
Ta structure n'est pas globale, donc elle n'est pas connue en dehors de la fonction dans laquelle tu l'as déclarée.
Remets le nouveau message d'erreur lors de la compilation.
Cordialement
Je constate dans ton code plusieurs erreurs.
Tout d'abord pourquoi faire de l'allocation dynamique alors que tu connais ta longueur à la déclaration ? Un simple char variable[50] suffirait.
t[i]={....} que tu as mis en commentaire, ne peut pas marcher sauf à la déclaration.
Ta structure n'est pas globale, donc elle n'est pas connue en dehors de la fonction dans laquelle tu l'as déclarée.
Remets le nouveau message d'erreur lors de la compilation.
Cordialement
kilian
Messages postés
8732
Date d'inscription
vendredi 19 septembre 2003
Statut
Non membre
Dernière intervention
5 février 2025
1 526
16 janv. 2008 à 22:48
16 janv. 2008 à 22:48
Ah mais il fallait le dire que c'était deux fichiers!
En ce cas il faut déclarer ton type de manière globale et complète pour les deux.
L'idéal: tu écris un fichier etiquettes.h dans le quel tu mets
Tu l'inclues dans tes deux fichiers C et tu peux maintenant utiliser cette structure tranquillement:
#include "etiquettes.h"
En ce cas il faut déclarer ton type de manière globale et complète pour les deux.
L'idéal: tu écris un fichier etiquettes.h dans le quel tu mets
struct Etiquette{ int adresse; char nom[20]; };
Tu l'inclues dans tes deux fichiers C et tu peux maintenant utiliser cette structure tranquillement:
#include "etiquettes.h"
ilan27
Messages postés
394
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
15 juin 2009
36
16 janv. 2008 à 23:04
16 janv. 2008 à 23:04
EEEEXCELLENT!!!!!
Mille bravos!, admire le travail:
0 errors, 0 warnings
Un grand merci, ça me désespérait. ;)
(J'ai rajouté à etiquette.h le tableau de struct)
==>Je récapitule:
On "globalise" la structure et le tableau de structure dans un '.h' qu'on inclut dans les fichiers qui l'utilisent
On n'oublie pas de retirer le tableau des arguments, sans oublier les '.h'
Merci kilian!
Mille bravos!, admire le travail:
0 errors, 0 warnings
Un grand merci, ça me désespérait. ;)
(J'ai rajouté à etiquette.h le tableau de struct)
==>Je récapitule:
On "globalise" la structure et le tableau de structure dans un '.h' qu'on inclut dans les fichiers qui l'utilisent
On n'oublie pas de retirer le tableau des arguments, sans oublier les '.h'
Merci kilian!
kilian
Messages postés
8732
Date d'inscription
vendredi 19 septembre 2003
Statut
Non membre
Dernière intervention
5 février 2025
1 526
17 janv. 2008 à 00:59
17 janv. 2008 à 00:59
Nononon........ On ne globalise que le type!
De manière générale:
_ On s'arrange pour qu'un type soit global (pour qu'il soit visible de partout), d'ailleurs je vois pas l'interêt d'un type local en C.
_On s'arrange pour qu'une variable soit locale (les variables globales, ça fout le bordel dans le code)
De manière générale:
_ On s'arrange pour qu'un type soit global (pour qu'il soit visible de partout), d'ailleurs je vois pas l'interêt d'un type local en C.
_On s'arrange pour qu'une variable soit locale (les variables globales, ça fout le bordel dans le code)
16 janv. 2008 à 21:06
le (char *) est inutile et dangereux. Il ne faut pas "caster" (convertir) le retour de malloc.
des fois c'est nécessaire