IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Avis Calculatrice


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut Avis Calculatrice
    Bonjour, j'ai développé une calculatrice en console.

    Petite info, je ne suis pas en étude d'informatique

    Elle n'est pas au top niveau optimisation . Mais elle fonctionne. Enfin d’après mes essais

    Je voudrai vos avis sur la méthode, vos conseils, et au passage me remonter les erreurs .

    Elle est plutôt évolué, car elle est capable de traiter
    (+18.56*2)-((-10.56++2.23)*3.56) = 66.774797
    Voici le code complé
    Main.c
    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
    /*
    Cette calculatrice est la version 1.0
     
    Fonctionne avec des nombres positif ou négatif.
    Elle gère les priorités des parenthèses, multiplications et des divisions.
    Il ne faut pas de caractère d'espacement
    Les nombres decimaux se font via un point
     
    Edité par Florian P.
     
    Version 1.0 le 06/01/2014*/
     
    #include <stdio.h>
    #include <stdlib.h>
    #include "calcul.h"
    #include "gestion.h"
     
    int						main(void)
    {
    	char operation[TAILLE_CHAR+1] = "(+18.56*2)-((-10.56++2.23)*3.56)";
    	char resusltat[TAILLE_CHAR+1] = { 0 };
     
    	if(calcul(operation, resusltat) != ERREUR)
    		printf("%s = %s.\n", operation, resusltat);
     
    	pause();
     
    	return EXIT_SUCCESS;
    }
    annexe Calculatrice.h
    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
    #include "annexe Calculatrice.h"
    #include "calcul.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
     
    char*						controleOperation(char s[])
    {
    	int i;
    	int parenthese;
     
    	for (parenthese = 0, i = 0; s[i] != '\0'; i++)
    	{
    		if (isdigit(s[i]))
    			;
    		else
    			switch (s[i])
    		{
    				case '.':
    					if (isdigit(s[i - 1]) && isdigit(s[i + 1]))
    						;
    					else
    						return &s[i];
    					break;
    				case '+': case '-': case '*': case '/': case '%':
    					if (i > 0)
    					{
    						if (isdigit(s[i - 1]) || s[i - 1] == '+' || s[i - 1] == '-' || s[i - 1] == '(' || s[i - 1] == ')' || s[i - 1] == '*' || s[i - 1] == '/')
    							;
    						else
    							return &s[i];
    					}
    					if (isdigit(s[i + 1]) || s[i + 1] == '+' || s[i + 1] == '-' || s[i + 1] == '(' || s[i + 1] == ')')
    						;
    					else
    						return &s[i + 1];
    					break;
    				case'(': case')':
    					parenthese = (s[i] == '(') ? parenthese + 1 : parenthese - 1;
     
    					if(parenthese < 0)
    						return &s[i]; break;
    				default: return &s[i]; break;
    		}
    	}
     
    	return (parenthese == 0) ? NULL : &s[0];
    }
     
    void						fonctionErreur(const char operation[], const char *cErreur, char resultat[])
    {
    	resultat[0] = 'E';
    	resultat[1] = 'R';
    	resultat[2] = 'R';
    	resultat[3] = 'E';
    	resultat[4] = 'U';
    	resultat[5] = 'R';
    	resultat[6] = '\0';
    	printf("%s invalide, '%c'.\n", operation, *cErreur);
    }
    gestion.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include "gestion.h"
    #include <stdio.h>
    #include <stdlib.h>
     
    void					pause(void)
    {
    	puts("Appuyer sur entrer pour continuer...");
    	getchar();
    }
    calcul.c
    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
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #include "calcul.h"
    #include "Annexe Calculatrice.h"
    #include <string.h>
    #include <ctype.h>
     
    static void				effacerParenthese(char operation[])
    /*
    Efface les parenthèses qui suit un nombre seul entouré de parenthèses*/
    {
    	int i, j, nbNombre, curseur, memoireI, fin;
    	char memoire[TAILLE_CHAR] = { 0 };
     
    	for (memoireI = - 1, i = nbNombre = 0, curseur = DEHORS; operation[i] != '\0' && operation[i] != ')'; i++)
    	{
    		if (operation[i] == '(')
    		{
    			memoireI = i;
    			nbNombre = 0;
    			curseur = DEHORS;
    		}
    		else
    		{
    			if (isdigit(operation[i]))
    			{
    				if (curseur == DEHORS)
    					nbNombre++;
     
    				curseur = DEDANS;
    			}
    			else if (curseur == DEDANS  && operation[i] == '.')
    				;
    			else
    				curseur = DEHORS;
    		}
    	}
    	fin = i;
     
    	if (nbNombre == 1 && memoireI != -1)
    	{
    		for (j = i = 0; i < memoireI; j ++, i ++)
    			memoire[j] = operation[i];
    		for (i = memoireI + 1; i < fin; i++, j++)
    			memoire[j] = operation[i];		
    		for (i++; operation[i] != '\0'; i++)
    		{
    			if (operation[i] != '#')
    			{
    				memoire[j] = operation[i];
    				j++;
    			}	
    		}
     
    		memoire[j] = '\0';
     
    		strcpy(operation, memoire);;
    	}
     
    }
     
    static void				placeNombre(char operation[], const double nb)
    /*
    Remplace dans opération les caractères '#" par nb*/
    {
    	int i, j, memoire;
    	char nbTxt[TAILLE_CHAR + 1] = { 0 };
    	char copie[TAILLE_CHAR + 1] = { 0 };
     
    	sprintf(nbTxt, "%f", nb);
     
    	for (i = 0; operation[i] != '\0' && operation[i] != '#'; i++)
    		copie[i] = operation[i];
    	memoire = i;
     
    	if (operation[i] == '#')
    	{
    		for (j = 0; nbTxt[j] != '\0'; j++, i++)
    			copie[i] = nbTxt[j];
     
    		for (j = memoire; operation[j] != '\0' && operation[j] == '#'; j++)
    			;
     
    		for (; operation[j] != '\0'; j++, i++)
    			copie[i] = operation[j];
    	}
     
    	copie[i] = '\0';
     
    	strcpy(operation, copie);
    }
     
    static int				cherchePriorite(const char operation[], const int position)
    {
    	int i, memoire, pos = (operation[position] == '(') ? position + 1: position;
    	int curseur = DEHORS;
     
    	for (i = memoire = pos; operation[i] != '\0' && operation[i] != ')'; i++)
    	{
    		if (operation[i] == '*' || operation[i] == '/')
    		{
    			memoire = i;
    			break;
    		}
    		else if ((operation[i] == '+' || operation[i] == '-') && curseur == DEDANS)
    			memoire = i;
     
    		if (isdigit(operation[i]))
    		{
    			if (curseur == DEHORS)
    				curseur = DEDANS;
    		}
    		else if (operation[i] == '.' && curseur == DEDANS)
    			;
    		else
    			curseur = DEHORS;
    	}
     
    	if (memoire == 0)
    		return FIN;
     
    	memoire--;
    	while (memoire >= 0)
    	{
    		if (isdigit(operation[memoire]) && memoire > 0)
    			memoire--;
    		else
    			break;
    	}
     
    	if (operation[memoire] == '.')
    	{
    		memoire--;
    		while (memoire >= 0)
    		{
    			if (isdigit(operation[memoire]) && memoire > 0)
    				memoire--;
    			else
    				break;
    		}
    	}
    	if (operation[memoire] == '+' || operation[memoire] == '-' )
    	{
    		if (memoire - 1 > 0)
    		{
    			if (!isdigit(operation[memoire - 1]))
    				memoire--;
    		}
     
    	}
     
    	if (operation[memoire] != '(')
    		return (memoire != 0) ? memoire + 1 : memoire;
    	else
    		return memoire + 1;
    }
     
    static int				lireNombre(char operation[], char lect[], const int tailleLect, int *indice, int *type, const int signe)
    // Cherche le nombre ou le signe suivant en fonction de l'indice.
    // Retourne le signe ou le nombre dans lect
    // Type prend SIGNE si c'est un signe, sinon NOMBRE
    // Les caractères deja lu sont remplacé par '#'
    {
    	int i, j, memoire;
     
    	if (signe == NON && (*indice) > 0)
    	{
    		if (operation[*indice] == '*' || operation[*indice] == '/' || operation[*indice] == '+' || operation[*indice] == '-' && (!isdigit(operation[*indice])))
    		{
    			lect[0] = operation[*indice];
    			lect[1] = '\0';
    			operation[*indice] = '#';
    			(*indice)++;
    			(*type) = SIGNE;
     
    			return OUI;
    		}
    	}	
     
    	for (i = memoire = *indice; operation[i] != '\0'; i++)
    	{
    		if (operation[i] == '(')
    			memoire = i;
    		else if (operation[i] == ')')
    			break;
     
    	}
     
    // Cherche s'il y a une multiplication ou division
    		memoire = cherchePriorite(operation, memoire);
    		if (memoire == FIN)
    			return FIN;
    // Copie le nombre
     
    		j = 0;
    		if (operation[memoire] == '+' || operation[memoire] == '-')
    		{
    			lect[j] = operation[memoire];
    			operation[memoire] = '#';
    			memoire++;
    			j++;
    			lect[j] = '\0';
    		}
    		for (; isdigit(operation[memoire]) ; memoire++, j++)
    		{
    			lect[j] = operation[memoire];
    			operation[memoire] = LU;
    		}
    		lect[j] = '\0';
    		if (operation[memoire] == '.')
    		{
    			lect[j] = operation[memoire];
    			operation[memoire] = LU;
     
    			j++;
    			memoire++;
     
    			for (; isdigit(operation[memoire]); memoire++, j++)
    			{
    				lect[j] = operation[memoire];
    				operation[memoire] = LU;
    			}
    			lect[j] = '\0';
    		}
     
    	(*indice) = (operation[memoire] != '\0')? memoire: 0;
    	(*type) = NOMBRE;
    	return OUI;
    }
     
    int						calcul(char operation[], char resultat[])
    {
    	char* erreur = NULL;
    	int i, k, signe;
    	char lect[TAILLE_LECT+1] = { 0 };
    	int type = 0;
    	double nb[2] = { 0.0 };
    	double nbResultat = 0.0;
     
    // Cherche '=' ou '\n' et le supprime
    	if ((erreur = strchr(operation, '=')) != NULL)
    		*erreur = '\0';
    	else if ((erreur = strchr(operation, '\n')) != NULL)
    		*erreur = '\0';
     
    // Contrôle les caractères restant
    	if ((erreur = controleOperation(operation)) != NULL)
    	{
    		fonctionErreur(operation, erreur, resultat);
    		return ERREUR;
    	}
     
    // Copie opération dans mémoire
    	strcpy(resultat, operation);
     
    // Calcul le résultat
    	i = 0;
    	k = 0;
    	signe = NON;
    	do
    	{
    		if (lireNombre(resultat, lect, TAILLE_LECT, &i, &type, signe) != OUI)
    		{
    			type = FIN;
    		}
    		if (type == NOMBRE)
    		{
     
    			nb[k] = strtof(lect, NULL);
    			k++;
    		}
    		else if (type != FIN)
    		{
    			switch (lect[0])
    			{
    				case'+': signe = ADDITION; break;
    				case'-': signe = SOUSTRACTION; break;
    				case'*': signe = MULTIPLICATION; break;
    				case'/': signe = DIVISION; break;
    			}
    		}
     
    		if (k > 1 && type != FIN)
    		{
    			switch (signe)
    			{
    			case ADDITION: nbResultat = nb[0] + nb[1]; break;
    			case SOUSTRACTION: nbResultat = nb[0] - nb[1]; break;
    			case MULTIPLICATION: nbResultat = nb[0] * nb[1]; break;
    			case DIVISION: nbResultat = nb[0] / nb[1]; break;
    			}
    			// Placer résultat
    			placeNombre(resultat, nbResultat);
     
    			// Efface les Parenthese si besoin
    			effacerParenthese(resultat);
     
    			k = 0;
    			i = 0;
    			signe = NON;
    		}
    	} while (type != FIN);
    	return OUI;
    }
    calcul.h
    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
    #ifndef CALCUL
     
    #define CALCUL 1
     
    #define ERREUR -1
     
    #define TROUVE 0
     
    #define LU '#'
     
    #define SIGNE 1
    #define NOMBRE 0
    #define FIN -1
     
    #define TAILLE_LECT 20
     
    #define OUI 1
    #define NON 0
     
    #define DEDANS 1
    #define DEHORS 0
     
    #define TAILLE_CHAR 100
     
    #define ADDITION 1
    #define SOUSTRACTION 2
    #define MULTIPLICATION 3
    #define DIVISION 4
     
    int							calcul(char s[],char resultat[]);
     
    #endif
    gestion.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #ifndef GESTION
    #define GESTION 1
     
    void					pause(void);
     
    #endif
    ANNEXE_CALCULATRICE.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #ifndef ANNEXE_CALCULATRICE
     
    #define ANNEXE_CALCULATRICE 1
     
    char*						controleOperation(char s[]);
    void						fonctionErreur(const char operation[], const char cErreur[], char resultat[]);
     
    #endif
    Merci de votre aide et bonne lecture

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    C'est une façon bizarre de procéder, se balader dans l'expression comme ça et l'exécuter directement.

    Généralement, quand on a une telle expression, on la traduit en quelque chose qui représente mieux un arbre de calcul (vrai arbre, expression postfixe, etc.) qu'on évalue ensuite avec une pile (il faut une pile (ou deux, je ne sais plus) aussi pour la traduction, au passage).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti Avatar de toutgrego
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2013
    Messages
    217
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2013
    Messages : 217
    Points : 350
    Points
    350
    Par défaut
    J'ai pas tout lu mais, on est obligé de mettre les parenthèses pour les priorités d'opération ?
    F*ck it ! Do it !

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    plombier
    Inscrit en
    Décembre 2012
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : plombier
    Secteur : Bâtiment

    Informations forums :
    Inscription : Décembre 2012
    Messages : 31
    Points : 25
    Points
    25
    Par défaut
    Non. Les multiplications et divisions sont prioritaire

    Par contre, le signe multiplié doit être ecrit.
    Exemple:

    (x+y)z n'est pas valide

    Je vais voir pour faire des piles.

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

Discussions similaires

  1. Comparatif des hébergeurs payants : Vos avis
    Par RideKick dans le forum Hébergement
    Réponses: 346
    Dernier message: 12/03/2017, 10h47
  2. [Avis] Les meilleurs programmes Java ?
    Par christopheJ dans le forum ImageJ
    Réponses: 69
    Dernier message: 07/10/2008, 01h12
  3. Donnez votre avis sur les articles de Developpez.com
    Par Geronimo dans le forum C++Builder
    Réponses: 13
    Dernier message: 14/01/2007, 22h00
  4. Qui se sert de Together ici ? votre avis ?
    Par Matthieu Brucher dans le forum Autres
    Réponses: 28
    Dernier message: 25/08/2006, 09h44
  5. Donnez votre avis sur les articles de Developpez
    Par Anomaly dans le forum Contribuez
    Réponses: 37
    Dernier message: 29/05/2006, 21h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo