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 :

Calculatrice RPN et chaine de caractères


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut Calculatrice RPN et chaine de caractères
    Bonjour,

    Je suis entrain de programmer une calculatrice RPN qui repose sur une pile FIFO (first-in, first-out).
    J'ai réussi a mettre au point la pile avec ses fonction dérivées : empiler dépiler, etc.
    Dans les conditions de cet exercice, il me faut pouvoir dupliquer le sommet de la pile en tapant "DUP", inverser les deux dernier éléments en tapant "SWAP" et enfin affiche le contenu de la pile en tapant "STACK"

    J'ai réussi à programmer ces fonctions : DUP, SWAP, STACK.

    La pile fonctionne bien dès que tu entres un chiffre ou un opérateur, l'instruction c=getcher() résout le problème, par contre je suis embêté car je n'arrive pas à trouver l'astuce qui me permet de renter DUP, SWAP et STACK. Je n'arrive pas à trouver le(s) instruction(s) nécessaire(s) pour que le programme fasse la différence entre (nombre, opérande) et les chaines de caractère voulues.

    J'ai pensé à un tableau de chaine de caractère pour entrer mes donnés, sauf que dans ce cas je perds la simplicité de getchar() et je ne peux plus exécuter mes opérations.

    merci,

  2. #2
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Je ne comprends pas comment tu peux utiliser getchar() avec des nombres (>9) ? Tu dois du coup déjà avoir un 'accumulateur' pour ton parsing non ? Et sans bout de code c'est dur à saisir.

    En gros, y'a deux approches:
    - tu garde ton getchar() et si ce n'est pas un opérateur (+-/* sur un seul char), tu doit buffuriser l'entrée et mettre ça dans un tableau/chaîne allouée et parser plus tard quand tu tombe sur un séparateur (espace je suppose), et voir si c'est un nombre ou un de tes 'fonctions' DUP...)
    - tu récupère toute l'entrée (avec fgets), puis tu découpe ta chaîne avec strtok ou strtok_r et enfin tu parse.

  3. #3
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    En effet, getcher() ne me permet pas de prendre des nombres, elle prend juste les chiffres : hypothèse à éliminer !

    J'ai pensé à un tableau qui prend tout en entée : caractère, nombre, float, opérateur, etc. Mais il me faut trouver comment faire le trie après ?!
    En tant que débutant en langage C, je n'ai toujours pas réussi à dépasser cet obstacle.

    Peux-tu détailler un petit plus, et étape par étape ce que tu me proposes ?

    merci,
    PedroL

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    Pour faire simple :

    scanf(%f) //me donne la main de faire entrer un float
    c=getchar() // me donne la main pour entrer un caractère. Utile pour entre les symboles +*-/

    char TAB [10] // me permet de faire l'input des commandes DUP, SWAP et STACK

    Comment faire pour avoir une commande, voire une fonction qui me permet d'entrer tous ces types tout en ayant la main de les partager :
    - si c'est un float---> l'empiler
    - Si c'est un opérateur ---> dépiler et faire l'opération
    - Si c'est : DUP, SWAP ou STACK ---> exécuter les fonctions qu'il y a derrière

    voilà, j'espère que c'est plus simple comme ça.

  5. #5
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Perso, je voyais quelque-chose comme ca:
    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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define BUF_SIZE 256
     
    struct ctx {
    	int foo;
    };
     
    static void init_context(struct ctx *ctx)
    {
    	ctx->foo = 0;
    	return;
    }
     
    static int parse(const char *s, struct ctx *ctx)
    {
    	char *string;
    	char *ptr, *tmp, *save;
    	if ((string = strdup(s)) == NULL) {
    		/* FIXME */
    		return 1;
    	}
    	for (tmp = string; (ptr = strtok_r(tmp, " \n", &save)); tmp = NULL) {
    		float f;
    		printf("token '%s'\n", ptr);
    		if (strcmp(ptr, "DUP") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "PUSH") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "+") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "-") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "*") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "/") == 0) {
    			/* FIXME */
    		} else if (sscanf(ptr, "%f", &f) == 1) {
    			/* FIXME */
    			printf("found float: %f\n", f);
    		} else {
    			printf("invalid token %s\n", ptr);
    			/* FIXME */
    		}
    	}
    	free(string);
    	return 0;
    }
     
    static void test_fgets(struct ctx *ctx)
    {
    	char buffer[BUF_SIZE];
     
    	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
    		if (parse(buffer, ctx) != 0) {
    			/* FIXME */
    		}
    	}
    	/* FIXME */
    	return ;
    }
     
     
    int main (void)
    {
    	struct ctx ctx;
    	init_context(&ctx);
    	test_fgets(&ctx);
    	return 0;
    }
    Exemple:
    > echo "3 2 + DUP FOO BAR 32 44 PUSH" | ./rpn"
    token '3'
    found float: 3.000000
    token '2'
    found float: 2.000000
    token '+'
    token 'DUP'
    token 'FOO'
    invalid token FOO
    token 'BAR'
    invalid token BAR
    token '32'
    found float: 32.000000
    token '44'
    found float: 44.000000
    token 'PUSH'
    >

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    That's It !

    reste à déchiffrer le code maintenant.

    merci,

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    Bonjour,

    Il s'agit toujours de cette fameuse calculette. J'ai implémenté mes fonctions dans les deux fichiers mystack.h et mystack.c ci-joints.

    J'essaye de faire un essai avec le code suivant :
    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
    #include<stdio.h>
     
    #include "mystack.h"
     
    int main()
    {
        Stack S;
     
        init(&S);
     
        MyStackPrint(&S);
     
        push(&S, 2.31);
     
        push(&S, 1.19);
     
        push(&S, v[top-1]);
     
        MyStackPrint(&S);
     
        printf("Popped value is: %f\n",pop(&S));
     
        push(&S, 6.8);
     
        MyStackPrint(&S);
     
        push(&S, pop(&S) + pop(&S));
     
        MyStackPrint(&S);
     
        printf("%d\n", full(&S));    	
     
        return 0;
     
    }
    et je veux avec l'instruction "push(&S, v[top-1]);" dupliquer le sommet de la pile, sauf que le compilateur ne reconnait pas ce que c'est que 'v' et ce que c'est que 'top'. Je ne comprends pas où est l'erreur ! pourtant j'ai bien déclaré ma pile au début de main avec l'instruction "Stack S;"
    voici le retour de mon shell :
    tstack.c: In function ‘main’:
    tstack.c:15: error: ‘v’ undeclared (first use in this function)
    tstack.c:15: error: (Each undeclared identifier is reported only once
    tstack.c:15: error: for each function it appears in.)
    tstack.c:15: error: ‘top’ undeclared (first use in this function)
    merci
    Fichiers attachés Fichiers attachés

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    Re-bonjour,

    J'ai essayé avec push(&S, S->v[S->(top-1)]); mais ça ne marche pas :

    tstack.c: In function ‘main’:
    tstack.c:15: error: invalid type argument of ‘->’ (have ‘Stack’)
    tstack.c:15: error: expected identifier before ‘(’ token

  9. #9
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 33
    Par défaut
    Je viens de trouver mon erreur ! c'est normale qu'il n'y ait pas reconnaissance des arguments. Il serait donc plus judicieux de programmer mes fonction en dehors du main().
    Je suis néanmoins face à un autre problème :
    J'ai pu programmer la fonction PUSH qui empile un float, mais je n'arrive pas à comprendre pourquoi elle ne marche pas dans ce main(). Voir ligne n°25.
    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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "mystack.h"
     
    #define BUF_SIZE 256
     
     
    int parse(const char *s)
    {
    	Stack S;
    	init(&S);
     
    	char *string;
    	char *ptr, *tmp, *save;
    	if ((string = strdup(s)) == NULL) {
    		/* FIXME */
    		return 1;
    	}
    	for (tmp = string; (ptr = strtok_r(tmp, " \n", &save)); tmp = NULL) {
     
    		float f;
    		//printf("token '%s'\n", ptr);
    		if (sscanf(ptr, "%f", &f) == 1) {
    			push(&S,f);
    			//printf("found float: %f\n", f);
    		}
    		else if (strcmp(ptr, "DUP") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "SWAP") == 0) {
    			/* FIXME */
    		}else if (strcmp(ptr, "STACK") == 0) {
    			MyStackPrint(&S);
    		} else if (strcmp(ptr, "+") == 0) {
    			add(&S);
    		} else if (strcmp(ptr, "-") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "*") == 0) {
    			/* FIXME */
    		} else if (strcmp(ptr, "/") == 0) {
    			/* FIXME */
    		}  else {
    			printf("invalid token %s\n", ptr);
    			/* FIXME */
    		}
    	}
    	free(string); 
    	return 0;
    }
     
    int main (void)
    {
     
    	char buffer[BUF_SIZE];
     
    	while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
     
    		//if (parse(buffer) != 0) {
    			/* FIXME */
    		//}
    		parse(buffer);
    	}
    	/* FIXME */
    	return 0;
    }
    La compilation se fait sans erreur mais lorsque je demande l'affichage du contenu de la pile, ma fonction d'affichage retourne "Stack is empty !".
    Bizarre !!!

    merci,

Discussions similaires

  1. Réponses: 9
    Dernier message: 23/12/2013, 16h40
  2. coder une calculatrice qui prend en paramètre une chaine de caractère
    Par AnozerOne dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 22/05/2010, 17h34
  3. Réponses: 9
    Dernier message: 17/01/2003, 11h45
  4. Lire Une Chaine De Caractères
    Par Jonathan_Korvitch dans le forum C
    Réponses: 12
    Dernier message: 07/01/2003, 05h37
  5. Réponses: 2
    Dernier message: 06/12/2002, 07h50

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