TheRogerFederer
Messages postés256Date d'inscriptionmercredi 31 mars 2010StatutMembreDernière intervention10 mars 2016
-
Modifié par TheRogerFederer le 7/10/2015 à 11:43
TheRogerFederer
Messages postés256Date d'inscriptionmercredi 31 mars 2010StatutMembreDernière intervention10 mars 2016
-
27 nov. 2015 à 09:07
Bonjour, je reviens vers vous, car cela faisait un petit moment ! Voici l'énoncé de mon problème :
"Saisir les noms des étudiants et, pour chaque étudiant, sa moyenne. Afficher les noms
des étudiants qui sont au dessus de la moyenne de la classe. Il n'y a pas plus de 40
étudiants et on arrêtera la saisie en posant la question à l'utilisateur."
l'algo qui était attendue suite a mes essais était le suivant :
programme moyennesup s_etudiants : structure nom : chaine moy : réel finstructure t_etudiant[1..40] : s_etudiant moyenne : réel rep : caractere nb, k : entier debut nb <- 0 // compteur d'étudiants moyenne <- 0 // cumul des moyennes //--- saisie des informations --- repeter nb <- nb + 1 afficher "nom de l'étudiant = " saisir t_etudiant[nb].nom afficher "moyenne de l'étudiant = " saisir t_etudiant[nb].moy moyenne <- moyenne + t_etudiant[nb].moy afficher "voulez-vous continuer ? (O/N) " saisir rep jusqu'à rep = "N" ou nb = 40 //--- calcul de la moyenne --- moyenne <- moyenne / nb //--- affichage des étudiants au dessus de la moyenne --- pour k de 1 à nb si t_etudiant[k].moy > moyenne alors afficher t_etudiant[k].nom finsi finpour fin
et j'ai codé cela :
#include <stdio.h>
#include <conio.h>
#include <string>
// -- Programme Principal --
void clear (void) {
while (getchar () != '\n') ;
}
int main()
{
// -- Déclarations --
struct s_etudiants {
const char nom ;
double moyenne ;
};
char rep = 'n' ;
double moyenne = 0 ; // Cumul des moyennes
int nbre = 0 ; // Compteurs d'étudiants
int k ;
t_etudiant[40] = s_etudiants ;
// -- Saisie des informations --
do
{
printf(" Nom de l'\x85tudiant = ") ;
scanf("%c",&t_etudiant[nbre].nom) ;
printf(" Moyenne de l'\x85tudiant = %lf ", moyenne) ;
scanf("%lf",&t_etudiant[nbre].moyenne) ;
moyenne = moyenne + t_etudiant[nbre].moyenne ;
printf(" Voulez-vous continuez ? (O/n) ") ;
clear () ;
scanf("%c",&rep) ;
nbre ++ ;
}
while(rep == 'n' || nbre = 40) ;
// -- Calcul de la moyenne --
moyenne = (moyenne / nbre) ;
// -- Affichage des étudiants au dessus de la moyenne --
for (k = 1; k <= nbre; nbre++)
{
if (t_etudiant[k].moyenne > moyenne)
{
printf(" Afficher t_\x85tudiant = ", t_etudiant) ;
}
}
getch() ;
return 0 ;
}
j'ai dessus 3 erreurs en supposant biensure que le programme fasse bien ce qui est attendu :
lvalue required as left operand of assignment - line 44
expected primary-expression before ';' token - line 28
't_etudiant' was not declared in this scope - line 28
J'en avais bcp plus a la base, j'espère en avoir résolu certaine sans modifier le but final biensure !
A voir également:
Classe etudiant c++
Écrire un programme qui calcule la moyenne des notes en c++ - Meilleures réponses
Écrire un programme qui calcule la moyenne des notes - Meilleures réponses
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 7 oct. 2015 à 13:43
Bonjour.
Plusieurs erreurs:
l14: Si le champ est constant, comment vas-tu faire pour le modifier ?
l14: On s'attend à une chaîne de caractères (plusieurs caractères, donc), et tu indiques un seul caractère.
l21: D'où sort "t_etudiant" ? Où est-il déclaré ?
l37: Tu confonds encore affectation et comparaison.
l42: Un tableau, en C, commence à 0. Donc un tableau de taille 40 va de 0 à 39 compris.
l46: Un printf ne peut pas afficher un type personnalisé (une structure). C'est à toi d'afficher ses membres un à un (ou juste le membre qui t'intéresse, en l'occurence, ici, le nom).
PS: Je t'invite une fois de plus à "perdre du temps", pour en gagner. C'est-à-dire, à lire et faire tous les tutoriel que je t'ai proposé dans un précédent post. Ça se sent immédiatemment que ça n'a pas été fait, et que tu ne t'es toujours pas amélioré. Bien évidemment, libre à toi de faire ce que tu veux (scolairement faire tes devoirs, sans plus, et ne pas t'améliorer, ou bien ne pas hésiter à prendre les devants et drastiquement progresser).
TheRogerFederer
Messages postés256Date d'inscriptionmercredi 31 mars 2010StatutMembreDernière intervention10 mars 20161 7 oct. 2015 à 16:09
Ah oui merci beaucoup !
Pour répondre a tes questions par rapport au sujet :
- Tu parles de quel chanp celui de const char nom ??
j'ai mis un %s a la place de %c pour qu'il renvoie une chaine
-Pour t_etudiant, je pensais juste que l'on nommerai le tableau ainsi..................., donc c'est le nom du tableau pour moi
-pour l'affectation je pense avoir rectifé en mettant aussi le double = a 40
-a oui, donc a la place de " ", t_etudiant, il faut lui faire afficher le nom ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 Modifié par cptpingu le 8/10/2015 à 10:54
- Tu parles de quel chanp celui de const char nom ??
Vu que je t'ai indiqué la ligne, normalement, il ne devrait pas y avoir ambiguïté :p. Mais oui, le "const char nom" étant, "const" tu ne peux pas le modifier. Ce qui te sera très problématique quand tu vas demander un nom à l'utilisateur.
j'ai mis un %s a la place de %c pour qu'il renvoie une chaine
C'est mieux, mais maintenant, tu vas stocker une chaine dans un seul caractère ? Ne vois-tu pas un autre souci ?
Pour t_etudiant, je pensais juste que l'on nommerai le tableau ainsi..................., donc c'est le nom du tableau pour moi
À aucun moment tu ne définis/décris le type de "t_etudiant". Tu utilises cette variable comme si elle existait, alors que ce n'est pas le cas. Il te manque la déclaration. Le compilateur voit une variable t_etudiant et te dit: "Heu ok, c'est quoi le type de cette variable ? Où je peux trouver sa définition ?".
Tes trois principaux soucis, qui te bloquent dans cet exercice (dans l'ordre):
La lecture sérieuse de ces 3 tutos (que je te conseille de faire bien après la lecture des autres tutos mentionnés avant cela), te permettra de te corriger tout seul les erreurs restantes, et rendre cet exercice complètement trivial.
TheRogerFederer
Messages postés256Date d'inscriptionmercredi 31 mars 2010StatutMembreDernière intervention10 mars 20161 21 oct. 2015 à 14:47
Bonjour, après avoir lu les tutos conseillés, j'avoue avoir compris certaines choses que je n'avais pas compris mais je comme je ne comprends pas malheureusement encore tout, j'ai encore du mal a corriger mes erreurs ! Je les comprends maintenant et les vois maintenant mais pas plus....................
On va le faire ensemble par étape. Dans mon premier post, je te posais pas mal de questions. Essaie d'y répondre, ce sont des pistes pour t'aiguiller.
Poste aussi ton nouveau programme corrigé, avec ce que tu as appris dans les tutos (même si celui-ci n'est pas encore fonctionnel).
D'accord eh bien pour la 1) j'ai enfin compris ce que veut dire const................
la 2) que doit-on écrire alors ? string ? Le seul problème c'est que j'utilise eclipse et eclipse ne reconnait pas le string meme quand j'(#include <string.h>), ou alors faut t'il mettre char[k] avec k un nombre quelconque ??
3) t_etudiant comme je l'avais dis auparavant je pensais que c'étais le nom du tableau.................., j'ai quand meme pris le soin de le déclarer auparavant en int........
4) Pour ceci : le == est une comparaison et le = une affectation normalement ??
5) Pour les tableaux je ne fais plus l'erreur ou presque plus normalement j'ai compris :)
6) La par contre je ne vois pas trop, dans les exemples de ce lien : (https://openclassrooms.com/courses/apprenez-a-programmer-en-c/creez-vos-propres-types-de-variables), par exemple : On envoie la variable utilisateur.nom à scanf qui écrira directement dans notre variable utilisateur. c'est pas ce que j'ai fais quand j'écris par exemple : "t_etudiant[nbre].moyenne", sinon mon nouveau code n'a pas beaucoup bougé, le voila :
int main()
{
// -- Déclarations --
struct s_etudiants
{
unsigned char nom ;
double moyenne ;
};
char rep = 'n' ;
double moyenne = 0 ; // Cumul des moyennes
int nbre = 0 ; // Compteurs d'étudiants
int k ;
int t_etudiant[39] = {s_etudiants} ;
// -- Saisie des informations --
do
{
printf(" Nom de l'\x85tudiant = ") ;
scanf("%s",&t_etudiant[nbre].nom) ;
printf(" Moyenne de l'\x85tudiant = %lf ", moyenne) ;
scanf("%lf",&t_etudiant[nbre].moyenne) ;
moyenne = moyenne + t_etudiant[nbre].moyenne ;
printf(" Voulez-vous continuez ? (O/n) ") ;
scanf("%c",&rep) ;
nbre ++ ;
}
while(rep == 'n' || nbre == 39) ;
// -- Calcul de la moyenne --
moyenne = (moyenne / nbre) ;
// -- Affichage des étudiants au dessus de la moyenne --
for (k = 1; k <= nbre; nbre++)
{
if (t_etudiant[k].moyenne > moyenne)
{
printf(" Afficher t_\x85tudiant = ", t_etudiant[nbre].nom) ;
}
}
getch() ;
return 0 ;
}
Je précise au passage que j'ai 7 erreurs :
expected ',' or ';' before 'struct' line 24
expected primary-expression before 'struct' line 24
request for member 'moyenne' in 't_etudiant[k]', which is of non-class type 'int' line 49
request for member 'moyenne' in 't_etudiant[nbre]', which is of non-class type 'int' line 34
request for member 'moyenne' in 't_etudiant[nbre]', which is of non-class type 'int' line 35
request for member 'nom' in 't_etudiant[nbre]', which is of non-class type 'int' line 32
request for member 'nom' in 't_etudiant[nbre]', which is of non-class type 'int' line 51
Je précise du coup que les lignes que je t'affiche son par rapport a mon fichier donc plus les bonnes quand je les colles ici...................
(PS : Surtout ne me donne pas le programme corrigé pour le moment, je voudrais que tu m'explique d'abord stp :))
2 choix se présente à toi:
- En C, on utilise une chaîne de caractère fixe, par exemple 32 caractères (j'ai pris 32 arbitrairement), soit: char nom[32];
- En C++, on peut directement utiliser un std::string (string n'est pas reconnu, c'est bien std::string qu'il faut indiquer). Pourquoi "std::" ? C'est un peu tôt pour le détailler, mais ça fait parti de la STL (la bibliothèque de base du C++), et il faut le préciser.
3) t_etudiant comme je l'avais dis auparavant je pensais que c'étais le nom du tableau.................., j'ai quand meme pris le soin de le déclarer auparavant en int........
Simple petit problème de syntaxe. Je te donne des exemples pour que tu comprennes mieux.
1 entier: int entier;
32 entiers: int entiers[32];
1 étudiant: s_etudiant etudiant;
32 étudiants: s_etudiant etudiants[32];
4) Pour ceci : le == est une comparaison et le = une affectation normalement ??
Tout à fait
5) Pour les tableaux je ne fais plus l'erreur ou presque plus normalement j'ai compris :)
Presque :). Le fait que tu déclares un s_etudiant à 39 éléments au lieu de 40, me faire dire que tu confonds encore. Je vais repréciser, "au cas où".
Exemple:
1 tableau de 20 entiers: int tab[20];, va de 0 à 19, soit: de tab[0] jusqu'à tab[19];
Donc un tableau de 40 étudiants: s_etudiant etudiants[40], qui ira de 0 à 39, soit de etudiants[0] jusqu'à etudiants[39];
Ne pas confondre la déclaration, où tu dis combien tu veux d'éléments, et l'utilisation, ou tu donnes l'index de ton élément.
Cas extrême, pour bien comprendre: un tableau de taille 1 élément: int tab[1], qui ne possedera bien qu'un seul élément à la position 0, soit tab[0].
Autre exemple plus concret pour bien comprendre:
// 0, 1, 2, 3
int tab[4] = {45,78,21,3}; // Déclaration de *4* éléments
printf("%i\n", tab[0]); // Accès à un élément.
printf("%i\n", tab[1]);
printf("%i\n", tab[2]);
printf("%i\n", tab[3]);
Les scanf ne sont pas problématiques, c'était surtout la ligne 46 de ta première version. Tu l'as corrigé dans la deuxième version. Le seul défaut, c'est que tu as oublié le format du printf. => printf("Afficher t_\x85tudiant = %s\n", t_etudiant[nbre].nom) ;
TheRogerFederer
Messages postés256Date d'inscriptionmercredi 31 mars 2010StatutMembreDernière intervention10 mars 20161 23 oct. 2015 à 11:33
2) Mouai d'accord, je me doutais bien qu'on allait faire comme cela :)
3) J'ai remarqué que tu avait mis des s à étudiant et entier quand ils y en a plusieurs, et pas mis quand c'étais 1 seul chose de traité............................ normalement les noms des variables ne doivent pas changer sinon le programme ne reconnait pas (sauf si elles sont déclarés bien sure...)..............??
5) Ah ouiiiiii d'accord, on a 40 étudiants qui sont "rangés et numérotés" dans un tableau d'indice 0 à 39 c'est ça ??
Dans ton exemple : le premier printf affichera : 45, le deuxieme : 78, etc.................??
6) Le fait que j'oublie le (%s\n) me plante tout l'affichage de (printf("Afficher t_\x85tudiant = %s\n", t_etudiant[nbre].nom) ;)
???
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 23 oct. 2015 à 12:08
3) J'ai remarqué que tu avait mis des s à étudiant et entier quand ils y en a plusieurs, et pas mis quand c'étais 1 seul chose de traité............................ normalement les noms des variables ne doivent pas changer sinon le programme ne reconnait pas (sauf si elles sont déclarés bien sure...)..............??
J'ai nommé ça "arbitrairement" avec un "s" parce que ça me semblait plus logique, pour l'exemple. J'aurais très bien pu appeler ça: int toto[42]. Bien évidemment, le nom de variable doit être le même. Donc si chez toi, tu appelles ça: s_etudiants etudiant[40]; alors oui, il n'y aura pas de "s".
5) Ah ouiiiiii d'accord, on a 40 étudiants qui sont "rangés et numérotés" dans un tableau d'indice 0 à 39 c'est ça ??
Dans ton exemple : le premier printf affichera : 45, le deuxieme : 78, etc.................??
C'est exactement ça.
6) Le fait que j'oublie le (%s\n) me plante tout l'affichage de (printf("Afficher t_\x85tudiant = %s\n", t_etudiant[nbre].nom) ;)
???
Oublie le %s, et tu ne verras pas apparaître le "nom".
Oublie le \n, et ta ligne peut se faire potentiellement "manger". C'est-à-dire, que sur certains terminal, si la toute dernière ligne n'a pas de saut de ligne, alors elle peut ne pas apparaître.
Tu cliques sur mon pseudo. Tu vas arriver sur mon profil. Il ne te reste qu'à m'envoyer un message privé en appuyant sur le bouton "Lui écrire un message".
Donc je comprend bien quelle lettre mettre pour un char, un int, un double etc................. mais je ne savais pas que pour les unsigned char était différent au niveau des lettres a mettre dans un scanf ?
D'ailleurs voici un screen shot de ce qu'il me fait :
donc apres la question, impossible de marquer quoique ce soit...................
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 Modifié par cptpingu le 3/11/2015 à 13:55
Petite notion de cours, qui devrait suffire à résoudre ton souci:
Le %s de scanf, veut dire qu'il veut un tableau.
Le %i veut dire qu'il veut un pointeur sur un entier.
etc...
Je ne vais pour l'instant pas rentrer dans la notion de pointeur. La chose que tu dois retenir est la suivante:
- Une valeur "normale" se lit via scanf avec "&ma_var"
- Un tableau (et donc aussi une chaîne de caractères) se lit via scanf avec "ma_var"
Exemple:
char c = 'e';
int i = 56;
char s[32] = "coucou";
printf("%c %i %s\n", c, i, s);
scanf("%c", &c);
scanf("%i", &i);
scanf("%s", s);
printf("%c %i %s\n", c, i, s);
Le C est sympa, et si tu mets un "&" devant un tableau, il l'accepte quand même.
De plus, une chaîne de caractères n'est pas unsigned, mais signed (si tu veux *vraiment* lire un unsigned char, il faut un truc du genre %hhu). Je t'invite à apprendre la doc de printf et scanf par coeur, puisque chaque format est différent (signed ou unsigned, float ou double, entier court ou long, etc...). Et il y en a beaucoup :).
Le %s de scanf, veut dire qu'il veut un tableau.
Le %i veut dire qu'il veut un pointeur sur un entier.
etc...
Je ne vais pour l'instant pas rentrer dans la notion de pointeur. La chose que tu dois retenir est la suivante:
- Une valeur "normale" se lit via scanf avec "&ma_var"
- Un tableau (et donc aussi une chaîne de caractères) se lit via scanf avec "ma_var"
Mais d'autre moins :
" Le C est sympa, et si tu mets un "&" devant un tableau, il l'accepte quand même.
De plus, une chaîne de caractères n'est pas unsigned, mais signed (si tu veux *vraiment* lire un unsigned char, il faut un truc du genre %hhu). Je t'invite à apprendre la doc de printf et scanf par coeur, puisque chaque format est différent (signed ou unsigned, float ou double, entier court ou long, etc...). Et il y en a beaucoup :). "
En attendant il ne m'affiche plus aucune erreur, ni warning mais maintenant il me fait autre chose de bizarre :
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 Modifié par cptpingu le 3/11/2015 à 16:14
Pour repréciser/résumer:
- un scanf d'un "char" (ou "signed char" c'est pareil) est %c.
- un scanf d'un "unsigned char" est %hhu.
- On préfère utiliser des char pour représenter des chaînes de caractères (plutôt que des unsigned char).
- Il existe beaucoup beaucoup de formats différents pour scanf et printf, et il faut avoir la doc sous les yeux (même si on est expérimenté).
il me fait autre chose de bizarre
Regarde bien tes "bornes". Tu commences à 1 et tu finis à "taille". Alors que tu devrais aller de 0 à "taille - 1" (ton "for" et ton "nbr++" sont faux).
Regarde aussi ta condition de lecture (while). Pour moi, il est aisé de dépasser 39 (mal sécurisé). En effet, tant que je met "n", je peut avancer à l'infini et largement dépasser la limite.
PS: Tu peux utiliser les balises < block> </block>pour citer du texte.
Pour le reste j'ai fais une erreur bête sur nbre ++ je pense, regarde je te montre :
Par contre pour la question du while et du 39 tu as raison, il est facile de la dépasser mais je ne sais pas pourquoi et je ne vois pas comment l'écrire autrement pour que ce soit plus sécurisé................ :(
Il y a néanmoins du progrès dans l'affichage......
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 Modifié par cptpingu le 5/11/2015 à 10:54
- La boule for est déjà mieux. Généralement, on fait: "int k = 0; k < nbre; ++k", mais "int k = 0; k <= nbre - 1; ++k" est tout aussi valable.
- Ton nbre++ est mal placé. Quand tu entres dans ton do...while, tu incrémentes nbre, et donc celui-ci vaut 1. Donc la première case dans laquelle tu commences à écrire est celle numérotée 1. Or, un tableau commence à 0... Je te laisse corriger ce souci.
- Ta boucle do...while a pour condition: *tant que* on appuie sur 'n' OU bien si nbre == 39, alors "boucler". 2 soucis: quand on veut continuer, on appuie pas sur 'n'. "nbre" ne sera égale à 39 qu'une seule fois. Je t'invite à tester tes deux conditions séparemment (tu en retire une temporairement pour tester). Ça te permettra de comprendre tes erreurs (ici de logiques pas de syntaxes).
PS: Copie ton code dans des balises de code, mais ne poste pas des images, ce n'est pas pratique (pas de copier coller possible, lourd à charger).