Probleme avec le code source

Fermé
jhonbouda Messages postés 25 Date d'inscription samedi 21 juin 2014 Statut Membre Dernière intervention 30 décembre 2014 - 10 juil. 2014 à 20:56
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 - 11 juil. 2014 à 11:50
Bonjour,


j'ai finalement pu realise une partie du programme mais lorsque je l'execute le programme s'arrete sans que toutes les procedure ne soit realisee
mon code source:

/*voila la version amelioree du menu qui m'a ete propose sur un forum
sur ce forum on m'a conseille d'utilise des fonctions pour rendre mon code plus lisible et comprehensible*/


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

/* on utilise la directive define d'apres mes recherche elle permet de creer des macros qui permet remplacer des substitu a un bout de code
je vois que la par exemple quand 1 est associe a cheque */
#define QUITTER 0
#define CHEQUE 1
#define FACTURE 2
#define CONSO 3

//=====================================================================================================================
//Les structures

typedef struct cheque cheque;
struct cheque
{
int numcheque;
int numcompte;
float montantpaye;
char nomclient[20];
int codefacture;
};


typedef struct facture facture;
struct facture
{
int code;
char *nom;
int bp;
char ville[20];
int tel;
float montant;
int index_deb;
int index_fin;
};


//lews compteurs
int i, j;
i = 0;
j = 0;

//variables gloales
int p_unitaire = 0;
float taxe = 0;

//Lesd fonctions

float calcul_montant(int d, int f)
{
return (f-d)*p_unitaire*(1 + taxe);
}

void definir_donnees() //une fonction pour definiur le prix unitaire et la taxe
{
do
{
printf("Entrer le montant unitaire : "); scanf("%d", &p_unitaire);
printf("Entrer la valeur de la taxe : "); scanf("%f", &taxe);
system("cls");
}while(p_unitaire <= 0 && (taxe <= 0 || taxe > 1));

}

//=====================================================================================================================

/* quelqu'un sur un forum m'a conseille d'utilise pour vider la memoire tampon je pense que c pour eviter les
problemes si par exemple l'utilisateur se trompe a plusieurs reprise en entrant de chaines ou des chiffes non mentionnes */
void viderbuffer()
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}

void creer_cheque(cheque t_cheque[]) //prend en pararmetre t_cheque
{
printf("\n\nCreation Cheque\n\n");

printf("entrez le numero d cheque:\t");
scanf("%d",&t_cheque[i].numcheque);
printf("numero du compte:\t");
scanf("%d",&t_cheque[i].numcompte);
printf("nom du client:\t");
scanf("%s",t_cheque[i].nomclient);
printf("code facture:\t");
scanf("%d",&t_cheque[i].codefacture);
//A la creation le montanmt a payer = 0
t_cheque[i].montantpaye = 0;
//on incremente le i
i++;
}

void creer_facture(facture t_facture[], cheque t_cheque[])
{
printf("\n\nCreation Facture\n\n");

m:printf("entrez le code:\t");
scanf("%d",&t_facture[j].code);
//on verifie si cecode exite car doit etre associe au cheque client
int k = 0; int ok = 0;
for(k = 0; k <= i; k++)
{
if(t_facture[j].code == t_cheque[k].codefacture)
{
ok = 1;
t_facture[j].nom = t_cheque[k].nomclient;

}
}
if(ok == 0)
{
printf("Ce code ne correspond a aucun cheque enregistre.\n");
goto m;
}
printf("bp:\t");
scanf("%d",&t_facture[j].bp);
printf("ville:\t");
scanf("%s",t_facture[j].ville);
printf("tel:\t");
scanf("%d",&t_facture[j].tel);
n:printf("index debut:\t");
scanf("%d",&t_facture[j].index_deb);
printf("index fin:\t");
scanf("%d",&t_facture[j].index_fin);
//on verifue si c'est ok
if(t_facture[j].index_deb > t_facture[j].index_fin)
{
printf("Erreur lors de l'enregistrement des index\n");
goto n;
}
j++;
}

void conso(facture t_facture[], cheque t_cheque[])
{
int temp, inc, a;

//Facture et cheque sont lies par le code Facture
printf("Entrer le Code Facture du cheque correspondant : ");
scanf("%d", &temp);
int trouve = 0;
for(inc = 0; inc <= i; inc++)
{
if(t_facture[inc].code == temp)
{
trouve = 1;
a = inc;
}
}
if(trouve == 1)
{
t_facture[a].montant = calcul_montant(t_facture[a].index_deb, t_facture[a].index_fin);
printf("\nClient %s\nVille %s\nBP %d\nPrix Unitaire %d\nTaxe %f\n", t_facture[a].nom,t_facture[a].ville,t_facture[a].bp, p_unitaire, taxe);
printf("\nLe montant de la facture est %2.f", t_facture[a].montant);
getch();
}
if(trouve == 0)
{
printf("Ce code Facture n'existe pas");
getch();
//conso(t_facture, t_cheque);
}



}
/*fonction menu pour afficher le menu*/
int menu()
{
int choixMenu, res;

printf("\n+---------------------------MENU-----------------------------+");
printf("\n| (1) | Creer un cheque |");
printf("\n| (2) | Creer une nouvelle facture |");
printf("\n| (3) | Calculer le montant de la consommation |");
printf("\n| (0) | quitter");
printf("\n+------------------------------------------------------------+\n");
do
{
printf("\nchoisissez le numero correspondant a ce que vous voulez faire : ");
res = scanf("%d",&choixMenu);/* la je pense qu'on a affecte la valeur a la variable res */
viderbuffer();/* on vide la memoire tampon*/
}while(res == 0 || choixMenu<QUITTER || choixMenu>CONSO);/*boucle qui demande de refaire le choix si la valeur ne correspond pas*/
return choixMenu;
}

int main()
{
//definition de deux tableau

cheque t_cheque[100]; //au besoin augmenter les taille
facture t_facture[100];

int choix;
while( (choix =menu() ) != QUITTER)
{
switch(choix)
{
case CHEQUE:
system("cls");
creer_cheque(t_cheque);
system("cls");
break;

case FACTURE:
system("cls");
definir_donnees();
system("cls");
creer_facture(t_facture, t_cheque);
system("cls");
break;

case CONSO:
system("cls");
conso(t_facture, t_cheque);
system("cls");
break;
}
printf("\n\n");
}
return 0;
}

5 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
10 juil. 2014 à 22:30
Bonjour,

Il vaut mieux rester sur le même topic tant que ton code n'est pas fonctionnel. Là, on en est au 4ème post portant sur le même code. Du coup, pas évident de suivre l'évolution...
Donc pour la suite, merci de ne plus ouvrir d'autres posts tant que cela concerne ce code.

Pour les balises code, c'est mieux mais je t'avais dit de plutôt utiliser <"code c">/*ici je mets mon code*/<"/code"> (sans guillemets).

Sinon, ton code a bien progressé ;-). Il est beaucoup plus lisible.
//lews compteurs
int i, j;
i = 0;
j = 0;

C'est déconseillé d'utiliser des variables globales... Surtout avec des noms de variable si courant... Sinon pour info, pas besoin de mettre i=0 et j=0 ; ça sera initialisé automatiquement à 0. Je te conseille de plutôt passer ces variables par paramètre. Les goto sont également à éviter. En revoyant ton algorithme, tu devrais pouvoir t'en passer.

char *nom;
Il faut faire de l'allocation dynamique si tu utilises un pointeur (malloc()...). Ou sinon, char nom[TAILLE];

Pour viderbuffer(), cela sert à vider les résidus de caractères dans le buffer clavier. Cela n'est pas forcément des erreurs de saisie de l'utilisateur.

t_facture[j].nom = t_cheque[k].nomclient;
Si nom est un pointeur comme tu as fait, cela est correct. Néanmoins, je pense que tu devrais plutôt passer par un tableau (cf. ci-dessus) et copier avec strcpy().

for(inc = 0; inc <= i; inc++)
Plutôt inc <i non ? Le dernier élément est i-1. i correspond à la prochaine place dans le tableau où tu peux écrire.

res = scanf("%d",&choixMenu);/* la je pense qu'on a affecte la
res ne sert à rien ici puisque tu ne t'en sers pas. Et non, cela ne contient pas le nombre tapé par l'utilisateur. Cela renvoie le nombre de variables correctement assignées. Ici, cela te renverra 1 (sauf erreur de saisie par l'utilisateur).

system("cls");
Ce n'est pas portable... Comme les fonctions déclarées dans conio.h d'ailleurs. Pourquoi effacer l'écran ? Cela énerve généralement plus qu'autre chose les personnes ;-).

Corrige déjà tout ça, reposte ton code et précise plus en détail ce qui ne fonctionne pas.
0
jhonbouda Messages postés 25 Date d'inscription samedi 21 juin 2014 Statut Membre Dernière intervention 30 décembre 2014 1
10 juil. 2014 à 23:47
merci pour les conseils en fait j'ai compiler l' ancien code par erreur, excusez moi car les deux fichiers .c ont exactement le meme nom j'ai oublie de supprimer celui qui ne marchait pas merci d'avoir pris le temps de me repondre et encore desole.
0
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 1 090
Modifié par [Dal] le 11/07/2014 à 10:03
int i, j;
i = 0;
j = 0;
C'est déconseillé d'utiliser des variables globales... Surtout avec des noms de variable si courant... Sinon pour info, pas besoin de mettre i=0 et j=0 ; ça sera initialisé automatiquement à 0.


juste pour clarifier : l'initialisation est faite implicitement à zéro pour les variables globales et les variables statiques, mais pas pour les variables locales à une fonction (variables dites "automatiques"), qui, si elles ne sont pas initialisées ont un contenu indéterminé.

comme c'est une subtilité du C, et qu'il faut très bien savoir ce que l'on fait et pourquoi si on choisit de ne pas initialiser explicitement, je suis plutôt d'avis que l'initialisation explicite est préférable systématiquement. Surtout lorsque l'on débute.


Dal
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 840
11 juil. 2014 à 11:13
Pour ma part, la règle est encore plus simple. Quand on débute : pas de variable globale :-).
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
[Dal] Messages postés 6193 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 4 juillet 2024 1 090
Modifié par [Dal] le 11/07/2014 à 11:51
si tu veux, mais puisque tu conseilles l'usage de variables locales, il faudra une initialisation explicite systématique, et qu'il mette à zéro ses compteurs.

sur res, je ne suis pas d'accord avec ton observation. Bien sûr res ne contient pas la saisie, comme tu le soulignes (et contrairement à ce qu'indique de façon trompeuse le commentaire dans le code), mais il est correctement utilisé dans le
}while(res == 0 || choixMenu<QUITTER || choixMenu>CONSO);
où, si l'utilisateur tape autre chose qu'un entier, le menu sera affiché de nouveau.

en passant, il devrait en revanche initialiser choixMenu, par exemple à -1, car là choixMenu peut contenir n'importe quoi avant le scanf, qui ne modifiera pas la valeur de choixMenu si l'entrée de l'utilisateur ne correspond pas au spécificateur.


Dal
0