erreur taille d'un tableau de structure

leomat
erreur taille d'un tableau de structure

bonjour a tous. alors voila, j'ai un petit prob au niveau des structures. je débute a ce niveau la donc je galère un peu.
voici mon code:

#include<stdio.h>

struct client;

main()
{
	int nbrClients,i;
	struct client baseDonnee[20];
	
	printf("Combien de clients voulez-vous? Max. 20");
	scanf("%d",&nbrClients);
	
	for(i=1;i<=nbrClients;i++)
	{
		printf("----> client n. %d <-----",i);
		printf("entrez son nom: ");
		scanf("%s", baseDonnee[i].nom);
		printf("entrez son prenom: ");
		scanf("%s", baseDonnee[i].prenom);
		printf("entrez son age: ");
		scanf("%d", baseDonnee[i].age);
		printf("entrez son sexe (h ou f): ");
		scanf("%c", baseDonnee[i].sexe);
	}
}
struct client
{
	char nom[15];
	char prenom[15];
	int age;
	char sexe;
};

comme erreur a la compil, il me donne

prog13.c: In function `main':
prog13.c:8: error: storage size of 'baseDonnee' isn't known

et pas moyen de comprendre pq :(

si vous pouviez m'aider ^^ :)

fredericmazue

Quote:
et pas moyen de comprendre pq

Parce que le compilateur ne peut voir la taille de client au moment où il compile la ligne et qu'il a besoin de cette taille pour calculer la taille de baseDonnee[20]

Tu fais une déclaration anticipée "struct client" Ca, ça dit que le type existe, mais ça ne donne pas sa taille au compilateur, qui ne fait pas la démarche d'aller voir "plus loin" dans le code. On est en C là, pas en Lisp ;)
Si tu enlèves cette déclaration anticipée et qu'à la place tu mets

struct client
{
char nom[15];
char prenom[15];
int age;
char sexe;
};

qui pour l'instant est à la fin du code, le compilateur pourras connaître la taille et ça compileras.

Les déclarations anticipées, ça ne marche pas dans tous les cas de figure.

leomat

euh ok j'vais essayer ca, meme si ca me dit rien du tout Oo
pour info, j'ai fait du java l'annéee passée, et j'en suis un peu nostalgique ^^
je teste ca et je vous dis quoi ;)
merci :)

leomat

ok ca marche comme ca, mais je n'ai pas bien compris pq.
parce qu'en fait, si on regarde mon code j'ai mis

struct client;

tout en haut de mon code, au dessus du main(), et si je me rappelle bien la théorie, en gros ca veut dire que dans mon main je vais faire appel a cette structure la, donc il saura aller voir plus loin si il en a besoin. en tous cas, pour ce qui est des fonctions et procédures, ca marche comme ca.
peut etre pas le cas avec les structures..
enfin merci bien ;)

fredericmazue

Quote:
parce qu'en fait, si on regarde mon code j'ai mis

Oui oui on a déjà regardé :evil:
Et expliqué ce qu'il est est de cette déclaration anticipée.
Quote:
je me rappelle bien la théorie, en gros ca veut dire que dans mon main je vais faire appel a cette structure la, donc il saura aller voir plus loin si il en a besoin

Et bien non justement, et je te l'ai expliqué dans mon post précédent. Tu ne lis pas ce qu'on te répond :?: :evil:
Quote:
pour ce qui est des fonctions et procédures

Oui parce que là la taille est connue, c'est la taille d'un pointeur.
Ah au fait, les procédures, ça n'existe pas en C. On est pas en Pascal là :twisted:
Quote:
peut etre pas le cas avec les structures

Et bien non, parce que au risque de me répéter, la taille de la structure n'est pas connue, au moment où le compilateur tombe sur baseDonne[20]
Quote:
enfin merci bien

Hum...j'espère qu'à l'avenir tu liras ce qu'on te répond.... :twisted:
Quote:
pour info, j'ai fait du java l'annéee passée, et j'en suis un peu nostalgique

Tu agraves vachement ton cas là :twisted:
dbobby

Merci Fred,
Ce que je n'aime pas avec les compilateurs C, c'est que les messages d'erreur sont souvent loin d'etre clair.
Moi avc ce code citer plus haut et compilateur open watcom j'avais plus des messages d'erreur , du genre nom, prenom, sexe inconnu.
Alors j'avais compris qu'on placant avanr c'est bon. mais j'avoue que j'avait pas compris pour quoi.
Vous comprennez maintenant pk j'aime tellement le basic. :oops:

fredericmazue

Quote:
Ce que je n'aime pas avec les compilateurs C, c'est que les messages d'erreur sont souvent loin d'etre clair.

C'est ma foi vrai (pour quelqu'un qui fait du basic), et pire en C++ :lol:
Mais il y a un remède tout simple: écrire du code qui compile :)

Quote:
Moi avc ce code citer plus haut et compilateur open watcom j'avais plus des messages d'erreur , du genre nom, prenom, sexe inconnu

Ca se sont des erreurs "en plus" de la première. En principe un compilateur C ou C++ ne s'arrête pas à la première erreur qu'il rencontre. Il continue sur sa lancée (selon sa configuration), ce qui fait qu'il ne voit après que des erreurs, réelles ou non, dont il ne faut pas tenir compte. Ce qui est important est le premier message d'erreur émis par le compilateur.

Quote:
Vous comprennez maintenant pk j'aime tellement le basic

Non :!:
Le basic t'a donné de très très mauvaises habitudes, c'est tout.
Mais moi, à mon tour, il y a quelque chose que je ne comprends pas. C'est toi qui a posé la question au départ ?
dbobby

bonjour,
Non c'est pas moi qui a ecrit le message initial, seulement ce code m'a intrigue par ce que j'aurai pense qu'il devait marcher.( je ne suis pas un grand specialiste du c) comme vous le savez deja.
et ce qui me nerve, peut etre je suis trop bete ,mais jai eu encore de warnings a la compilation.
C'est vrai qu'il fonctionne, mais il doit avoir qq chose qui ne vas pas.
A bientot
Dbobby

fredericmazue

Quote:
mais jai eu encore de warnings a la compilation.

lesquels ?

Quote:
C'est vrai qu'il fonctionne, mais il doit avoir qq chose qui ne vas pas.

Il fonctionne ? Hum... je ne dirais pas qu'il fonctionne. je dirais plutôt qu'il est plein de bugs.
Si on entre plus de 20 clients (rien ne l'empêche), il y a débordement de tampon.
Si on saisit un nom ou un prénom de plus de 14 (je dis bien 14 hein, pas 15) caractères, il y a encore débordement de tampon.
Bref ce code est une horreur.
dbobby

bonjour
celui ci
testchar.c(12): Warning! W304: Return type 'int' assumed for function 'main'
testchar.c(31): Warning! W107: Missing return value for function 'main'

Et pour le reste ce que vou dites je suis biensur d'accord. C'est pas un programme complet et/ou fini . Mais comme j'ai deja dit c'est pas moi qui l'a ecrit.

Maintenant si vous avez le temps dites moi pour quoi 14 et pas 15 caracteres
Merci et a bientot
Dbobby

fredericmazue

Quote:
testchar.c(12): Warning! W304: Return type 'int' assumed for function 'main'

Oui, celui là, c'est parce que le programme est mal formé, tout simplement. On devrait avoir

int main(void) {/* etc */}

Il faut un code de retour de main. Ce code de retour est utilisé par le système d'exploitation. La valeur 0 indiquant un succès.
main() c'était légal dans le C de l'âge de pierre, mais ça ne l'est plus en C89 ou C99. Apparement les compilateurs le tolèrent et émettent un avertissement.

Quote:
testchar.c(31): Warning! W107: Missing return value for function 'main'

Celui là est lié au précédent. Puisque main doit retourner une valeur, il faut définir cette valeur. par exemple:

return 0;

à la fin du programme. En C++, s'il n'y a aucune autre instruction return dans le main, le return 0; est implicite et on a pas besoin de le mettre, et le compilateur n'émet pas d'avertissement. Je ne sais pas ce qu'il en est de cette finesse en C. J'ai tendance à oublier le standard C faute de le pratiquer :oops: Apparement le return 0; n'est pas implicite. De toutes façons, C ou C++, je n'aime pas l'implicite. Je mets toujours explicitement une instruction return à la sortie du main, et il faut le faire à mon humble avis. Question de clarté du code.

Quote:
Maintenant si vous avez le temps dites moi pour quoi 14 et pas 15 caracteres

Très simple. En C une chaîne de caractères se termine par un octet nul. Si on saisi comme nom la chaine "A", soit une simple lettre, le tableau client.nom, pour reprendre l'exemple, va contenir les valeurs 65 et 0. Le 65 c'est pour le A et le 0 pour la fin de chaîne.
Donc si on entre un nom de 15 caractères, automatiquement il y aura un zéro en 16 eme position, c'est à dire au delà du tableau. On a donc un débordement.
dbobby

Tres bien, merci