2017-09-11 2 views
1

Je fais donc une simple calculatrice d'infixes. J'ai du mal à stocker un personnage et un double sur une pile. D'abord j'ai essayé de séparer les opérandes et l'opérateur comme vu dans le code ci-dessous, mais plus tard je me rends compte que je serais parti dans un gros problème.Plusieurs types de données dans une pile en C

Je suis un novice également dans l'utilisation des syndicats Que dois-je faire pour stocker un char et un double sur une seule pile?

est ici le code:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 


typedef union{ 
    char c; 
    double d; 
} Union; 

typedef struct Node{ 
    Union data; 
    struct Node *link; 
} Node; 

typedef struct Stack{ 
    Node *top; 
}Stack; 

void initialize_stack(Stack *stack) 
{ 
    stack->top=NULL; 
} 

    int is_stack_empty(Stack *stack) 
{ 
    return(stack->top==NULL); 
} 

void push_c(Stack *stack, char x) 
{ 
    Node *node=(Node*)malloc(sizeof(Node)); 

    if(node==NULL) 
    { 
     printf("Sorry no enough memory\n"); 
    } 
    else 
    { 
     node->data.c=x; 
     node->link=NULL; 
     if(is_stack_empty(stack)) 
     { 
      stack->top=node; 
     } 
     else 
     { 
      node->link=stack->top; 
      stack->top=node; 
     }  
    } 
} 

void push_d(Stack *stack, double x) 
{ 
    Node *node=(Node*)malloc(sizeof(Node)); 

    if(node==NULL) 
    { 
     printf("Sorry no enough memory\n"); 
    } 
    else 
    { 
     node->data.d=x; 
     node->link=NULL; 
     if(is_stack_empty(stack)) 
     { 
      stack->top=node; 
     } 
     else 
     { 
      node->link=stack->top; 
      stack->top=node; 
     }  
    } 
} 

void pop(Stack *stack) 
{ 
    Node *runner=stack->top; 
    if(is_stack_empty(stack)) 
    { 
     printf("Stack is empty.\n"); 
    } 
    else 
    { 
     stack->top=stack->top->link; 
     free(runner); 
    } 
} 



void print_stack_c(Stack *stack) 
{ 
    Node *runner=stack->top; 
    if(is_stack_empty(stack)) 
    { 
     printf("Stack is empty.\n"); 
    } 
    else 
    { 
     while(runner!=NULL) 
     { 
      printf("%c,",runner->data.c); 
      runner=runner->link; 
     } 
     printf("\n"); 
    } 
} 

void print_stack_d(Stack *stack) 
{ 
    Node *runner=stack->top; 
    if(is_stack_empty(stack)) 
    { 
     printf("Stack is empty.\n"); 
     } 
    else 
    { 
     while(runner!=NULL) 
     { 
      printf("%.4f,",runner->data.d); 
      runner=runner->link; 
      } 
     printf("\n"); 
    } 
} 

int main(){ 
    char input[150],output[150]; 
    int i; 
    double j; 
    char a[20]=""; 
    char b[20]=""; 
    char c[10],d[10]="",e[10]=""; 
    struct Stack operand; 
    struct Stack operator; 
    struct Stack tempstack; 


    initialize_stack(&tempstack); 
    initialize_stack(&operand); 
    initialize_stack(&operator); 

    scanf("%s",input); //store input to a string 


    //convert infix to postfix 
    for(i=0;i<strlen(input)-1;i++){ 

    if(input[i]==' '){ 
     continue; 
    } 
    else if(input[i]=='('){ 

     push_c(&tempstack,input[i]); 
    } 

    else if(isdigit((unsigned char)input[i]) || input[i] == '.'){ 
    strcpy(a,b);//clear 
    while(isdigit((unsigned char)input[i]) || input[i] == '.'){ 
    strncat(a,&input[i],1); 
    i++;   
    } 

    j=atof(a); 
    push_d(&operand,j); 
    } 

    else{ //operand 


    } 

    } 

    print_stack_c(&tempstack); 
    print_stack_d(&operand); 
    } 
+0

Vous devez également le type de magasin pour savoir ce qui est à l'intérieur de l'Union. Vous pouvez le faire comme ceci typedef union { char c; double d; } valeur; enum { double_t, operatuion_t } type de valeur; Typedef struct { valeur v; valuetype t; } stack_elem; – LZ041

+0

Comme LZ041 a dit, afin d'utiliser correctement les données stockées dans l'union, vous devez savoir si un caractère ou double a été stocké. Vous pouvez le faire en ajoutant une sorte de drapeau à votre structure de Node, que ce soit une énumération ou un autre type de données où vous pouvez stocker deux états différents, un qui indique que l'union de données contient un caractère et un état indiquant qu'il stocke un double. Vous devez définir l'indicateur dans le nœud en conséquence en même temps que vous stockez les données, puis vérifiez l'indicateur avant de récupérer les données. –

+0

* J'ai du mal à stocker un char et un double sur une pile. * Quel est le problème que vous rencontrez? –

Répondre

0

Voici une méthode:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <errno.h> 

#define SUCCESS 0 

typedef enum DATATYPES_E 
    { 
    DATATYPE_DOUBLE, 
    DATATYPE_CHAR 
    } DATATYPES_T; 

typedef union DATA_U 
    { 
    char c; 
    double d; 
    } DATA_T; 

typedef struct NODE_S 
    { 
    DATA_T   data; 
    DATATYPES_T dataType; 
    struct NODE_S *link; 
    } NODE_T; 

typedef struct STACK_S 
    { 
    NODE_T *top; 
    } STACK_T; 

int StackPushChar(STACK_T *stack, char x) 
    { 
    int  rCode=SUCCESS; 
    NODE_T *node; 

    errno=0; 
    node=malloc(sizeof(NODE_T)); 
    if(!node) 
     { 
     rCode=errno; 
     goto CLEANUP; 
     } 

    node->dataType = DATATYPE_CHAR; 
    node->data.c=x; 
    node->link=NULL; 
    if(stack->top) 
     { 
     node->link=stack->top; 
     stack->top=node; 
     } 
    else 
     stack->top=node; 

CLEANUP: 

    return(rCode); 
    } 

int StackPushDouble(STACK_T *stack, double x) 
    { 
    int  rCode=SUCCESS; 
    NODE_T *node; 

    errno=0; 
    node=malloc(sizeof(NODE_T)); 
    if(!node) 
     { 
     rCode=errno; 
     goto CLEANUP; 
     } 

    node->dataType = DATATYPE_DOUBLE; 
    node->data.d=x; 
    node->link=NULL; 
    if(stack->top) 
     { 
     node->link=stack->top; 
     stack->top=node; 
     } 
    else 
     stack->top=node; 

CLEANUP: 

    return(rCode); 
    } 

void StackPrint(STACK_T *stack) 
    { 
    NODE_T *runner=stack->top; 
    if(!stack->top) 
     { 
     printf("Stack is empty.\n"); 
     goto CLEANUP; 
     } 

    while(runner) 
     { 
     switch(runner->dataType) 
     { 
     case DATATYPE_DOUBLE: 
      printf("%.4f,",runner->data.d); 
      break; 

     case DATATYPE_CHAR: 
      printf("%c,", runner->data.c); 
      break; 
     } 

     runner=runner->link; 
     } 

    printf("\n"); 

CLEANUP: 

    return; 
    } 

int main() 
    { 
    int  rCode = SUCCESS; 
    STACK_T stack = 
     { 
     .top=NULL 
     }; 

    rCode=StackPushDouble(&stack, 3.1415926535); 
    if(rCode) 
     { 
     fprintf(stderr, "StackPushDouble() reports %d %s\n", rCode, strerror(rCode)); 
     goto CLEANUP; 
     } 

    rCode=StackPushChar(&stack, '+'); 
    if(rCode) 
     { 
     fprintf(stderr, "StackPushChar() reports %d %s\n", rCode, strerror(rCode)); 
     goto CLEANUP; 
     } 

    rCode=StackPushDouble(&stack, 6.02E23); 
    if(rCode) 
     { 
     fprintf(stderr, "StackPushDouble() reports %d %s\n", rCode, strerror(rCode)); 
     goto CLEANUP; 
     } 

    rCode=StackPushChar(&stack, '='); 
    if(rCode) 
     { 
     fprintf(stderr, "StackPushChar() reports %d %s\n", rCode, strerror(rCode)); 
     goto CLEANUP; 
     } 

    StackPrint(&stack); 

CLEANUP: 

    return(rCode); 
    } 
+0

Vous avez beaucoup de goto, mais vous ne nettoyez jamais ... –