2017-09-11 9 views
1

Also mache ich einen einfachen Infix-Rechner. Ich habe Probleme beim Speichern eines Char und einem Doppel auf einem Stapel.Mehrere Datentypen in einem Stapel in C

Zuerst habe ich versucht, die Operanden und Operator zu trennen, wie im Code unten zu sehen, aber später merke ich, dass ich in großen Schwierigkeiten gegangen wäre.

Ich bin ein Neuling auch in Gewerkschaften verwenden Was soll ich tun, um ein Char und ein Doppel nur auf einem Stapel zu speichern?

hier ist der 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

Sie müssen auch Speichertyp wissen, was in Vereinigung ist. Sie können es wie folgt tun: typedef union { char c; doppelt d; } Wert; enum { double_t, operatuion_t } Werttyp; typedef struct { Wert v; Werttyp t; } stack_elem; – LZ041

+0

Wie LZ041 sagte, um die in der Union gespeicherten Daten richtig zu verwenden, müssen Sie wissen, ob ein Zeichen oder ein Doppel gespeichert wurde. Sie können dies tun, indem Sie der Struktur Node eine Art Flag hinzufügen, sei es eine Aufzählung oder ein anderer Datentyp, in dem Sie zwei verschiedene Zustände speichern können, einen, der angibt, dass die Datenunion ein Zeichen enthält und einen Status, der angibt, dass sie gespeichert wird ein Doppel. Sie würden das Flag in Node entsprechend zur gleichen Zeit festlegen, zu der Sie die Daten speichern und dann das Flag überprüfen, bevor Sie die Daten abrufen. –

+0

* Ich habe Probleme beim Speichern eines Chars und eines Double auf einem Stack. * Was ist das Problem, das Sie haben? –

Antwort

0

Hier ist eine Methode:

#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

Sie haben eine Menge von CLEANUP, aber Sie reinigen nie ... –