tutorials.de Buch-Aktion 05/2012
Seite 1 von 3 123 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
32
ZUGRIFFE
2238
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Haaaaaallo Leute.

    Ich habe schon das gesamte Forum durchkämmt, also tut es mir leid, wenn dieses Thema doppelt drinsteht, aber ich habe alles gegeben.

    Kennt jemand ein Tutorial, dass einem beibringt, wie man einen Equation Solver in C programmiert?
    Also damit ihr wisst, was ich meine: Nachher soll ich so eine Funktion haben:
    Code c:
    1
    
    double dbValue = solveEquation("( 1 - 4 ) ^ 4 / ( 3 - 2 * 9 )");
    Ich find auch bei google nix gescheites, aber ich finde, dass ist eine nennenswerte Problemstellung...

    Danke im Voraus,
    mfG
    Me
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  2. #2
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Also ein Equation Solver ist etwas anderes. Mit einem Equation Solver kann man Gleichungen (mit Variablen) lösen. Du hast ja überhaupt keine Gleichung.

    Du möchtest anscheinend einfach nur den Wert eines math. Ausdruck berechnen, also einen Taschenrechner schreiben?

    Siehe http://www.tutorials.de/forum/c-c/24...im-parsen.html

    Gruß
    killerkirsche bedankt sich. 
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  3. #3
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Soo. Dank eurer Tollen hilfe konnte ich nun ein Programm schreiben. Es funktioniert bisher nur mit Termen ohne Klammern, aber es funktioniert (konnte keinen Fehler finden).
    Ich poste es mal hier, damit kommende Leser das Rad nicht neu erfinden müssen (so wie ich xD):
    So kann man einen Term, der als String gespeichert ist, ausrechnen.
    Ein Term-Ausrechner qusi.
    Code c:
    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
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define bool    unsigned char
    #define true    1
    #define false   0
    #define maybe   2
     
    /**
     *THIS PROGRAM CALCULATES A TERM SAVED IN A STRING
     *HERE SOME FACTS FOR VARIABLE-NOTATION (Var IS THE NAME OF THE VARIABLE)
     *
     *BASIC NOTATION:
     * TYP      NOTATION
     *-------------------
     * char     chVar
     * int      nVar
     * double   dbVar
     * char *   czVar  (most coders name it szVar)
     * struct   grVar
     * array    nnaVar (e.g. "int naVar[9]" or "double dbVar[9]" or "char czVar[9]".
                        In some cases I write chaVar[9] instead of czVar[9] because
                        I want to use the char-array as an Array and not as a string
                        .)
     *
     *SPECIAL NOTATION
     * TYP                  NOTATION
     *-------------------------------
     * struct grElement     grElVar
     * struct grTerm        grTmVar
    */
     
     
    struct grElement{
      double dbValue;
      char   chOperator;
    };
     
    struct grTerm{
      char *czTerm;
      int  nNextElementPosition;
    };
     
    /**
     * Returns true if chOp1 has got lower priority than chOp2
     * @param  chOp1  The first operator
     * @param  chOp2  The second operator
     * @return true if chOp1 has got lower priotity than chOp2, false if not
     */
    bool isLowerOperator(char chOp1, char chOp2){
      //there is one lowest operator namend "?"
      if(chOp1=='?' && chOp2!='?'){
        return true;
      } 
      if(chOp1=='+' || chOp1=='-'){
        if(chOp2=='*' || chOp2=='/'){
          //chOp1 < chOp2
          return true;
        }
        else{
          //chOp1 = chOp2
          return false;
        }
      }
      //It has to be '*' or '/'
      else{
        if(chOp2=='+' || chOp2=='/'){
          //chOp1 > chOp2
          return false;
        }
        else{
          //chOp1 = chOp2
          return false;
        }
      }
    }
     
    /**
     * Searches for the next element in a Term
     * @param  *grTmTerm   A grTerm-struct. nNextElementPosition will be manipulated
     * @return             A grElement-struct. chOperator is the identify what element it is:
     *                         chOperator == 'e' ==> there are no more elements
     *                         chOperator == 0   ==> it is a number (can be found in dbValue)
     *                         else              ==> it is an operator (+ * - /)
    */
    struct grElement *getNextElement(struct grTerm *grTmTerm){
      int i;                                           //The counter of the for-loop
      int nPartLength=1;                               //The length of the current element (min. 1)
      char ch;                                         //The current char checked by the for-loop
      char *czNumber;                                  //In this char * a dec number will be saved (copied out of czTerm)
      static struct grElement *grElReturn;             //The return struct
      grElReturn = malloc(sizeof(struct grElement));   //Allocating the size of the return struct
      
      //Proving if there are any more elements
      if((*grTmTerm).nNextElementPosition >= strlen((*grTmTerm).czTerm)){
        (*grElReturn).dbValue = 0;
        (*grElReturn).chOperator = 'e';
        return grElReturn;
      }
      
      //Searching the end of the element
        for(i=(*grTmTerm).nNextElementPosition;i<strlen((*grTmTerm).czTerm);i++){
          ch = *((*grTmTerm).czTerm+i);                            //Getting the char at i
          //Checking wether the element has ended now
          if(ch==' '){
            //It has ended
            ch = *((*grTmTerm).czTerm+i-1); //correcting the char
            break;
          }
          //It has not ended yet => Go on until it ends
          
          nPartLength++;              //The part becomes bigger if it is no operator
          
        }
        
      //Identifying the element  
      if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?'){
        //It is a operator
        (*grElReturn).dbValue    = 0;
        (*grElReturn).chOperator = ch;
      }
      else{
        //It is no operator, it is an operand
        czNumber = (char *)malloc((nPartLength+1)*sizeof(char));  //Getting the containing string
        
        strncpy(czNumber,(*grTmTerm).czTerm + (*grTmTerm).nNextElementPosition,nPartLength);  //Preparing the string to parse it to double
        (*grElReturn).dbValue    = strtod(czNumber,NULL);                                     //Parsing the string to a double
        (*grElReturn).chOperator = 0;                                                         //when chOperator == 0 the program knows that it is a number
        
        free(czNumber);
      }
      
      (*grTmTerm).nNextElementPosition += nPartLength;  //Next time we want to go a part further
      
      return grElReturn;
    }
     
     
    /**
     * Calculates a term. The term has to be formatted like this "### + ### - ### * ### / - ### ? 0", where ### can be any number.
     * Without a "? 0" at the end it wont work because in this program it is the lowest operator.
     */
    double calcTerm(char *czTerm){
      struct grTerm    grTmTerm;        //This struct is for the term we calc
      struct grElement *grElElement;    //In this struct we will save the new elements
      double *dbaOperandStack;          //This is the Operand-Stack
      char   *chaOperatorStack;         //And this is the Operator-Stack
      int    nOperandStackSize  = 0;    //The Operand-Stack's size
      int    nOperatorStackSize = 0;    //The Operator-Stack's size
      double dbReturn;                  //In this double we save the return-value
      
      /*
        If you do not know the words "operand" and "operator":
        operator = A letter/char which calculates two operands, e.g. : +,-,*,/
        operand  = A number with which whe can calculate, e.g. : 90;3.141;-7
      */
      
      //Initializing the term
      grTmTerm.czTerm               = czTerm;
      grTmTerm.nNextElementPosition = 0; 
      //Initializing the element  
      grElElement = malloc(sizeof(struct grElement));   //Allocating the size of the return struct
      //Initializing the stacks
      dbaOperandStack  = (double *)malloc(sizeof(double));
      chaOperatorStack = (char *)malloc(sizeof(char));
      
      
      
      //There has to be a first operand, so get one
      nOperandStackSize++;                         //When we get an operand, the stack grows
      dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double)); //When the stack grows we have to reallocate it
      grElElement = getNextElement(&grTmTerm);     //Then we get the Element
      //But we have to check if it is an operand
      if((*grElElement).chOperator!='e'){
        //It can be an operator or an operand
        if((*grElElement).chOperator!=0){
          //If the first element is an operator, the term has a syntax error, because a term cant start with "+-/*?"
          return 0.0;
        }
        else{
          //It is a operand so it has to be pushed on the operand-stack
          *(dbaOperandStack+nOperandStackSize-1) = (*grElElement).dbValue;
        }
      }
      else{
        //It is neither an operand nor an operator
        return 0.0;
      }
      
      //No we got a first operand and we can go through the whole term
      do{
        //At first we have to get the operator with which we deal
        grElElement = getNextElement(&grTmTerm);
        
        //Because of the do-while-loop we have to control the 'e'-case already here
        if((*grElElement).chOperator=='e'){
          break;
        }
        
        //Than we have to check if it really is a operator
        if((*grElElement).chOperator!=0){
          //Yes, it is an Operator
          //Now we want to know if it is a operator with lower priority than the one before
          if( !isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) || nOperatorStackSize==0){
              //The new operator has got a higher priority than the last operator
              //So we can put him easily on top of the stack
              
              nOperatorStackSize++;                                                                  //We want to put something on the stack so it has to grow
              chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));  //It grows so we have to reallocate it
              *(chaOperatorStack+nOperatorStackSize-1) = (*grElElement).chOperator;                  //Now we are able to add something
              
              //After adding an operator we need to add an operand
              
              grElElement = getNextElement(&grTmTerm);
              
              //But we cannot add it without controlling it
              if((*grElElement).chOperator != 0){
                //It can be anything but no number so the term is wrong and we return 0.0
                return 0.0;
              }
              
              nOperandStackSize++;                                                                    //We want to put something on the stack so it has to grow
              dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));  //It grows so we have to reallocate it
              *(dbaOperandStack+nOperandStackSize-1) = (*grElElement).dbValue;                        //Now we are able to add something
              
              //The stack-method for calculation terms has one mistake. If there is 
              //a '-' is works like a '- ('. So we have to delete all '-'
              if(*(chaOperatorStack+nOperatorStackSize-1)=='-'){
                *(chaOperatorStack+nOperatorStackSize-1)='+';
                *(dbaOperandStack+nOperandStackSize-1) = 0 - *(dbaOperandStack+nOperandStackSize-1);   
              }/*if(*(chaOperatorStack+nOperatorStackSize-1)=='-')*/
              
          }/*if( !isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) || nOperatorStackSize==0)*/
          
          //If the new Operator has lower priority than the last one on the stack
          //we can calculate the element before
          
          else{
            while( isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) && nOperandStackSize > 1){  
              //As long as the new operator has got a lower priority than the last one, we will calculate
              //We have to find out if it is a +,-,* or / (or even a ?)
              switch( *(chaOperatorStack+nOperatorStackSize-1)){
                case '+': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) + *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '-': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) - *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '*': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) * *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '/': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) / *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '?': //Nothing to do
                          break;
                default: //There has to be a false Term with an unknown operator, so return 0.0
                         return 0.0;
              }/*switch( *(chaOperatorStack+nOperatorStackSize-1))*/
              
            }/*while( isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) && nOperandStackSize > 1)*/
            
            //After we walked through the term we can finally add the new element
            
            //We want to add something, so the stacks have to grow
            nOperatorStackSize++;
            nOperandStackSize++;
            //The stacks' size changed so we have to reallocate them
            dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
            dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
            //Now we can add the new elements
            
            //At first the operator
            *(chaOperatorStack+nOperatorStackSize-1) = (*grElElement).chOperator;
            //Then the operand
            grElElement = getNextElement(&grTmTerm);
            //but not without checking
            if((*grElElement).chOperator != 0){
              //It can be anything but no number so the term is wrong and we return 0.0
              return 0.0;
            }
            *(dbaOperandStack+nOperandStackSize-1) = (*grElElement).dbValue;
              
            //The stack-method for calculation terms has one mistake. If there is 
            //a '-' is works like a '- ('. So we have to delete all '-'
            if(*(chaOperatorStack+nOperatorStackSize-1)=='-'){
              *(chaOperatorStack+nOperatorStackSize-1)='+';
              *(dbaOperandStack+nOperandStackSize-1) = 0 - *(dbaOperandStack+nOperandStackSize-1);            
            }/*if(*(chaOperatorStack+nOperatorStackSize-1)=='-')*/
          }/*else*/
        }/*if((*grElElement).chOperator!=0)*/
        else{
          //It is no operator so the term is wrong
          return 0.0;
        }
        
      }while((*grElElement).chOperator!='e');
     
      //Now we can set the return-value
      dbReturn = dbaOperandStack[0];
      //and free the allocated RAM
      free(dbaOperandStack);
      free(chaOperatorStack);
      free(grElElement);
      
      return dbReturn;
    }
     
    int main(int argc, char *argv[])
    {   
     
      struct grElement *grElElement;
      double dbC1,dbM1,dbC2,dbM2,dbC3,dbM3;
      dbC1 = 9 * -3 - 4 + -8 * 4 - 6;
      dbM1 = calcTerm("9 * -3 + -4 + -8 * 4 + -6 ? 0");
      dbC2 = 9 * -3 - 4 + -8 * 4 - 6;
      dbM2 = calcTerm("9 * -3 - 4 + -8 * 4 - 6 ? 0");
      dbC3 = 1 + 3 + 5 * 9 * -8 * 7 - 8 + 9;
      dbM3 = calcTerm("1 + 3 + 5 * 9 * -8 * 7 - 8 + 9 ? 0");
      printf("%f %f %f\n",dbC1,dbC2,dbC3);
      printf("%f %f %f\n",dbM1,dbM2,dbM3);
         
      free(grElElement);
       
      system("PAUSE");
      return EXIT_SUCCESS;
    }
    Geändert von killerkirsche (04.03.10 um 18:14 Uhr) Grund: musste noch ein paar Begriffe nennen, damit man es in der Suche findet
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  4. #4
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Hallo zusammen.

    Ich bin grade dabei auch klammerausdrücke zu erlauben, aber ich komme nicht weiter aufgrund eines Fehlers den ich nicht verstehe.
    Wenn ich in der haupt-routine den befehl
    Code c:
    1
    
    printf("");
    weglasse, will das programm nach dem ausführen nicht laufen und windows meldet einen fehler.
    Das macht doch keinen sinn.
    Hier der quellcode:
    main.c
    Code c:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    /*main.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "termcalc.h"
     
    int main(int argc, char *argv[])
    {   
     
      double dbC1,dbM1,dbC2,dbM2,dbC3,dbM3;
      dbC1 = 9 * -3 - 4 + -8 * 4 - 6;
      dbM1 = calcString("9 * -3 + -4 + -8 * 4 + -6");
      dbC2 = 9 * -3 - 4 + -8 * 4 - 6;
      dbM2 = calcString("9 * -3 - 4 + -8 * 4 - 6");
      dbC3 = 1 + 3 - ( 5 * 9 - 4 * ( 2 - 4 ) ) * -8 * 7 - 8 + 9;
      //printf("");
      dbM3 = calcString("1 + 3 - ( 5 * 9 - 4 * ( 2 - 4 ) ) * -8 * 7 - 8 + 9");
      printf("%f\t%f\t%f\n",dbC1,dbC2,dbC3);
      printf("%f\t%f\t%f\n",dbM1,dbM2,dbM3);
         
       
      system("PAUSE");
      return EXIT_SUCCESS;
    }

    termcalc.h
    Code c:
    1
    2
    3
    4
    5
    
    /*termcalc.h*/
    #ifndef TERMCALC_H
      #define TERMCALC_H
      double calcString(char *czTerm);
    #endif /* MYHEADER_H */

    termcalc.c
    Code c:
    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
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    
    /*termcalc.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define bool    unsigned char
    #define true    1
    #define false   0
    #define maybe   2
     
    /**
     *THIS PROGRAM CALCULATES A TERM SAVED IN A STRING
     *HERE SOME FACTS FOR VARIABLE-NOTATION (Var IS THE NAME OF THE VARIABLE)
     *
     *BASIC NOTATION:
     * TYP      NOTATION
     *-------------------
     * char     chVar
     * int      nVar
     * double   dbVar
     * char *   szVar
     * struct   grVar
     * array    nnaVar (e.g. "int naVar[9]" or "double dbVar[9]" or "char szVar[9]".
                        In some cases I write chaVar[9] instead of czVar[9] because
                        I want to use the char-array as an Array and not as a string
                        .)
     *
     *SPECIAL NOTATION
     * TYP                  NOTATION
     *-------------------------------
     * struct grElement     grElVar
     * struct grTerm        grTmVar
    */
     
     
    struct grElement{
      double dbValue;              //If the element is a number, the value will be
                                   //saved here
      char   chOperator;           //If the element is an operator, the char will
                                   //be saved here. this var indicates the type of
                                   //the element as well: If it is 0, it is an
                                   //operand, if not it is an operator
    };/*--struct grElement------*/
     
    struct grTerm{
      char *czTerm;                //The term as a string
      int  nNextElementPosition;   //Position of the next element we want to read. 
                                   //This Position is very import, especially for
                                   //terms containing brackets
      int  nDepth;                 //Mostly ignored by this code but can be 
                                   //important for later add-ons
    };/*--struct grElement------*/
     
    /*bool   isLowerOperator(char chOp1, char chOp2);
    struct grElement *getNextElement(struct grTerm *grTmTerm);
    double calcString(char *czTerm);*/
    double calcTerm(struct grTerm *grTmTerm);
     
    /**
     * Returns true if chOp1 has got lower priority than chOp2
     * @param  chOp1  The first operator
     * @param  chOp2  The second operator
     * @return true if chOp1 has got lower priotity than chOp2, false if not
     */
    bool isLowerOperator(char chOp1, char chOp2){
      //there is one lowest operator namend "?"
      if(chOp1=='?' && chOp2!='?'){
        return true;
      } 
      if(chOp1=='+' || chOp1=='-'){
        if(chOp2=='*' || chOp2=='/'){
          //chOp1 < chOp2
          return true;
        }
        else{
          //chOp1 = chOp2
          return false;
        }
      }
      //It has to be '*' or '/'
      else{
        if(chOp2=='+' || chOp2=='/'){
          //chOp1 > chOp2
          return false;
        }
        else{
          //chOp1 = chOp2
          return false;
        }
      }
    }/*--bool isLowerOperator(char chOp1, char chOp2)------*/
     
    /**
     * Searches for the next element in a Term
     * @param  *grTmTerm   A grTerm-struct. nNextElementPosition will be manipulated
     * @return             A grElement-struct. chOperator is the identify what element it is:
     *                         chOperator == 'e' ==> there are no more elements
     *                         chOperator == 0   ==> it is a number (can be found in dbValue)
     *                         else              ==> it is an operator (+ * - /)
    */
    struct grElement *getNextElement(struct grTerm *grTmTerm){
      int i;                                           //The counter of the for-loop
      int nPartLength=1;                               //The length of the current element (min. 1)
      char ch;                                         //The current char checked by the for-loop
      char *czNumber;                                  //In this char * a dec number will be saved (copied out of czTerm)
      static struct grElement *grElReturn;             //The return struct
      grElReturn = malloc(sizeof(struct grElement));   //Allocating the size of the return struct
      
      //Proving if there are any more elements
      if((*grTmTerm).nNextElementPosition >= strlen((*grTmTerm).czTerm)){
        (*grElReturn).dbValue = 0;
        (*grElReturn).chOperator = 'e';
        return grElReturn;
      }/*--if((*grTmTerm).nNextElementPosition >= strlen((*grTmTerm).czTerm))------*/
      
      //Searching the end of the element
        for(i=(*grTmTerm).nNextElementPosition;i<strlen((*grTmTerm).czTerm);i++){
          ch = *((*grTmTerm).czTerm+i);                            //Getting the char at i
          //Checking wether the element has ended now
          if(ch==' '){
            //It has ended
            ch = *((*grTmTerm).czTerm+i-1); //correcting the char
            break;
          }
          //It has not ended yet => Go on until it ends
          
          nPartLength++;              //The part becomes bigger if it is no operator
          
        }/*--for(i=(*grTmTerm).nNextElementPosition;i<strlen((*grTmTerm).czTerm);i++)------*/
        
      //Identifying the element  
      if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' ){
        //It is a operator
        (*grElReturn).dbValue    = 0;
        (*grElReturn).chOperator = ch;
      }/*--if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' )------*/
      else{
        //It is no operator, it is an operand
        czNumber = (char *)malloc((nPartLength+1)*sizeof(char));  //Getting the containing string
        
        strncpy(czNumber,(*grTmTerm).czTerm + (*grTmTerm).nNextElementPosition,nPartLength);  //Preparing the string to parse it to double
        (*grElReturn).dbValue    = strtod(czNumber,NULL);                                     //Parsing the string to a double
        (*grElReturn).chOperator = 0;                                                         //when chOperator == 0 the program knows that it is a number
        
        free(czNumber);
      }/*--if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' ) else ------*/
      
      (*grTmTerm).nNextElementPosition += nPartLength;  //Next time we want to go a part further
      
      return grElReturn;
    }/*--struct grElement *getNextElement(struct grTerm *grTmTerm)------*/
     
    /* 
     * Calculates a term. The term has to be formatted like this "### + ### - ### * ### / - ###", where ### 
     
    can be any number.
     * char *czTerm the term
     */
    double calcString(char *czTerm){
      char             *czTerm2;                  //The new - modified - term
      int              i,j;                       //Some little poor ints with big influences and connections to russian mafia
      struct grTerm    grTmTerm;                  //This struct is for the term we calc
      double           dbReturn;                  //This value will be returned
      int              nLength = strlen(czTerm);  //Length of the term
      int              nBrackets;                 //Number of brackets
      int              *naBrackets;               //Position of the brackets
      
      //At first we gonna count all closed brackets to input " ? 0"
      nBrackets=0;
      for(i=0;i<nLength;i++){
        if(czTerm[i]==')'){
          nBrackets++;
        }
      }
      
      //Now we know the number, but we want to know the positions as well
      naBrackets = (int *)malloc((nBrackets+2)*sizeof(int)); //We will save the position of the brackets here
      
      //Preparing the bracket-positions
      j                       = 1;                      //We gonna skip the first position because it has to be 0
      naBrackets[0]           = 0;                      //has to be 0, because we want to copy the string in front of the first bracket as well
      naBrackets[nBrackets+1] = nLength+nBrackets*4;    //And we want to copy the string after the last bracket
      
      for(i=0;i<nLength;i++){
        if(czTerm[i]==')'){
          naBrackets[j]=i;  //saving the position of the bracket
          j++;              //increasing j
        }
      }
      
      //We know where the brackets are and we knoe how much brackets there are
      //At first we malloc the RAM for czTerm2, we need "NUMBER OF BRACKETS" * 4
      //because "? 0 " has 4 chars and we need 4 additional chars for the last
      //" ? 0". ATTENTION: "? 0 " is not " ? 0" 
      czTerm2 = (char *)malloc( (nLength+(nBrackets*4)+4) * sizeof(char));
     
      
      //cleaning the string after allocating the RAM
      for(i=0;i<nLength+(nBrackets*4)+4;i++){
        czTerm2[i]='\0';
      }
      
      //Preparing "loop-variables"
      j = 0;
      
      //Then we add the "? 0 "
      if(nBrackets>0){
        //There are brackets so we need a loop
        for(i=0;i<nBrackets;i++){
          //Copying the string before the bracket
          for(j=naBrackets[i]+i;j<naBrackets[i+1];j++){
            czTerm2[j+i*4] = czTerm[j];
          }
          //Adding "? 0 )";
          czTerm2[(j++)+i*4] = '?';
          czTerm2[(j++)+i*4] = ' ';
          czTerm2[(j++)+i*4] = '0';
          czTerm2[(j++)+i*4] = ' ';
          czTerm2[(j++)+i*4] = ')';
        }/*for(i=0;i<nBrackets;i++)*/
        
        //Now we add the chars after the last bracket
        for(j=j-4;j<nLength+(nBrackets*4)+4;j++){
          czTerm2[j+nBrackets*4] = czTerm[j];
        }/*for(j=j-4;j<nLength+(nBrackets*4)+4;j++)*/ 
        
      }/*if(nBrackets>0)*/
      else{
        //There are no brackets so we can easily add the string
        for(j;j<nLength+(nBrackets*4)+4;j++){
          czTerm2[j+nBrackets*4] = czTerm[j];
        } 
      }/*if(nBrackets>0) else*/ 
      
      //At the end, there has to be a " ? 0"
      i = nLength+(nBrackets*4);
      czTerm2[i++] = ' ' ;
      czTerm2[i++] = '?' ;
      czTerm2[i++] = ' ' ;
      czTerm2[i++] = '0' ;
      czTerm2[i++] = '\0';
     
      //Initializing the term
      grTmTerm.czTerm               = czTerm2;
      grTmTerm.nNextElementPosition = 0; 
      grTmTerm.nDepth               = 0;
      
      //Calculating the term
      dbReturn = calcTerm(&grTmTerm);
      
      
      return dbReturn;
    };/*double calcString(char *czTerm)*/
     
    /**
     * Calculates a grTerm
     * @param  *grTmTerm a pointer to the term-struct (stuct grTerm)
     */
    double calcTerm(struct grTerm *grTmTerm){
      struct grElement *grElElement;    //In this struct we will save the new elements
      double *dbaOperandStack;          //This is the Operand-Stack
      char   *chaOperatorStack;         //And this is the Operator-Stack
      int    nOperandStackSize  = 0;    //The Operand-Stack's size
      int    nOperatorStackSize = 0;    //The Operator-Stack's size
      double dbReturn;                  //In this double we save the return-value
      double dbValue;                   //Just a little double
      
      
      /*
        If you do not know the words "operand" and "operator":
        operator = A letter/char which calculates two operands, e.g. : +,-,*,/
        operand  = A number with which whe can calculate, e.g. : 90;3.141;-7
      */
      
      //Initializing the element  
      grElElement = malloc(sizeof(struct grElement));   //Allocating the size of the return struct
      //Initializing the stacks
      dbaOperandStack  = (double *)malloc(sizeof(double));
      chaOperatorStack = (char *)malloc(sizeof(char));
      
      
      
      //There has to be a first operand, so get one
      nOperandStackSize++;                         //When we get an operand, the stack grows
      dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double)); //When the stack grows we have to reallocate it
      grElElement = getNextElement(grTmTerm);     //Then we get the Element
      dbValue     = 0;                            //And save it in this var;
      
      //But we have to check if it is an operand
      if((*grElElement).chOperator!='e'){
        //It can be an operator or an operand
        if((*grElElement).chOperator!=0){
          //It might be a bracket
          if((*grElElement).chOperator=='('){
            dbValue = calcTerm(grTmTerm);
          }
          else{
            //If the first element is an operator, the term has a syntax error, because a term cant start with "+-/*?"
            return 0.0;
          }
        }/*--if((*grElElement).chOperator!=0)------*/
        else{
          //It is a operand so it has to be pushed on the operand-stack
          dbValue = (*grElElement).dbValue;
        }/*--if((*grElElement).chOperator!=0) else ------*/
      }/*--if((*grElElement).chOperator!='e')------*/  
      else{
        //It is neither an operand nor an operator
        return 0.0;
      }/*--if((*grElElement).chOperator!='e') else------*/  
      *(dbaOperandStack+nOperandStackSize-1) = dbValue;
      //No we got a first operand and we can go through the whole term
      do{
        //At first we have to get the operator with which we deal
        grElElement = getNextElement(grTmTerm);
        
        //Because of the do-while-loop we have to control the 'e'-case already here
        if((*grElElement).chOperator=='e'){
          break;
        }
        
        //Than we have to check if it really is a operator
        if((*grElElement).chOperator != 0){
          //Yes, it is an Operator
          //Now we want to know if it is a operator with lower priority than the one
          //before or if it is a bracket   
          if((*grElElement).chOperator == ')' && (*grTmTerm).nDepth!=0){
            return dbaOperandStack[0];
          }
          else if((*grElElement).chOperator == ')' && (*grTmTerm).nDepth==0){
            //This is a mistake, there cannot be a closed bracket without an opnend
            //But we will return a value, as well        
            return dbaOperandStack[0];
          }
          
          if( !isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) || nOperatorStackSize==0){
              //The new operator has got a higher priority than the last operator
              //So we can put him easily on top of the stack
              
              
              nOperatorStackSize++;                                                                  //We want to put something on the stack so it has to grow
              chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));  //It grows so we have to reallocate it
              *(chaOperatorStack+nOperatorStackSize-1) = (*grElElement).chOperator;                  //Now we are able to add something
              
              //After adding an operator we need to add an operand
              
              grElElement = getNextElement(grTmTerm);
              
              //But we cannot add it without controlling it
              if((*grElElement).chOperator != 0 && (*grElElement).chOperator != '(' ){
                //It can be anything but no number so the term is wrong and we return 0.0
                return 0.0;
              }
              else if((*grElElement).chOperator == '(' ){
                //So it is a open bracket. When a bracket opens we need a recursion
                (*grTmTerm).nDepth++;
                dbValue = calcTerm(grTmTerm);
              }
              else{
                //No bracket, not operator ==> yeha it is an operand
                dbValue = (*grElElement).dbValue;
              }
              
              nOperandStackSize++;                                                                    //We want to put something on the stack so it has to grow
              dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));  //It grows so we have to reallocate it
              *(dbaOperandStack+nOperandStackSize-1) = dbValue;                                       //Now we are able to add something
              
              //The stack-method for calculation terms has one mistake. If there is 
              //a '-' is works like a '- ('. So we have to delete all '-'
              if(*(chaOperatorStack+nOperatorStackSize-1)=='-'){
                *(chaOperatorStack+nOperatorStackSize-1)='+';
                *(dbaOperandStack+nOperandStackSize-1) = 0 - *(dbaOperandStack+nOperandStackSize-1);   
              }/*if(*(chaOperatorStack+nOperatorStackSize-1)=='-')*/
              
          }/*if( !isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) || nOperatorStackSize==0)*/
          
          //If the new Operator has lower priority than the last one on the stack
          //we can calculate the element before
          
          else{
            while( ( isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) )&& nOperandStackSize > 1){  
              //As long as the new operator has got a lower priority than the last one, we will calculate
              //We have to find out if it is a +,-,* or / (or even a ?)
              switch( *(chaOperatorStack+nOperatorStackSize-1)){
                case '+': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) + *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '-': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) - *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '*': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) * *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '/': *(dbaOperandStack+nOperandStackSize-2) = *(dbaOperandStack+nOperandStackSize-2) / *(dbaOperandStack+nOperandStackSize-1);
                          nOperatorStackSize--;
                          nOperandStackSize--;
                          break;
                case '?': //Nothing to do
                          break;
                default: //There has to be a false Term with an unknown operator, so return 0.0
                         return 0.0;
              }/*switch( *(chaOperatorStack+nOperatorStackSize-1))*/
              
            }/*while( isLowerOperator( (*grElElement).chOperator,*(chaOperatorStack+nOperatorStackSize-1) ) && nOperandStackSize > 1)*/
            
            //After we walked through the term we can finally add the new element
            
            //We want to add something, so the stacks have to grow
            nOperatorStackSize++;
            nOperandStackSize++;
            //The stacks' size changed so we have to reallocate them
            dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
            dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
            //Now we can add the new elements
            
            //At first the operator
            *(chaOperatorStack+nOperatorStackSize-1) = (*grElElement).chOperator;
            //Then the operand
            grElElement = getNextElement(grTmTerm);
            //but not without checking
            if((*grElElement).chOperator != 0){
              //It can be anything but no number so the term is wrong and we return 0.0
              return 0.0;
            }
            else if((*grElElement).chOperator == '(' ){
              //So it is a bracket
              (*grTmTerm).nDepth++;
              dbValue = calcTerm(grTmTerm);
            }
            else{
              //jippi, it's an operand
              dbValue = (*grElElement).dbValue;
            }
            
            *(dbaOperandStack+nOperandStackSize-1) = dbValue;
              
            //The stack-method for calculation terms has one mistake. If there is 
            //a '-' is works like a '- ('. So we have to delete all '-'
            if(*(chaOperatorStack+nOperatorStackSize-1)=='-'){
              *(chaOperatorStack+nOperatorStackSize-1)='+';
              *(dbaOperandStack+nOperandStackSize-1) = 0 - *(dbaOperandStack+nOperandStackSize-1);            
            }/*if(*(chaOperatorStack+nOperatorStackSize-1)=='-')*/
          }/*else*/
        }/*if((*grElElement).chOperator!=0)*/
        else{
          //It is no operator so the term is wrong
          return 0.0;
        }
        
        //A little debug loop. I didn't deleted it, because it is very easy to debug
        //This code with this loop
        /*
        printf("\n\t\t----DEBUG----\n\t\t_____________\n");
        for(z=0;z<nOperandStackSize;z++){
          printf("\t\t%2i->%f\n",z,dbaOperandStack[z]);
        }
        */
        
      }while((*grElElement).chOperator!='e');
     
      //Now we can set the return-value
      dbReturn = dbaOperandStack[0];
      //and free the allocated RAM
      free(dbaOperandStack);
      free(chaOperatorStack);
      free(grElElement);
      
      return dbReturn;
    };/*double calcTerm(struct grTerm *grTmTerm)*/
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  5. #5
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Problem dahingegen gelöst, dass ich DEV-Cpp langsam (datei für datei) gelöscht habe, denn mit openwatcom gibts 0 probleme.
    Wie kann man nur nen compiler vertreiben, der so nen mist macht....
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  6. #6
    Avatar von Vereth
    Vereth Vereth ist offline Mitglied Brokat
    Registriert seit
    Nov 2009
    Ort
    Dortmund
    Beiträge
    372
    Ein paar Anmerkungen habe ich doch noch.
    • Möglicherweise hatte sich ein 'Müllzeichen' in den Quellcode eingeschlichen.
    • Für solche Problemstellungen verwendet man meistens einen Syntaxbaum.
    • Mit den Tools lex und yacc kann man sich die Arbeit wesentlich erleichtern. Bei GnuWin32 gibt es diese UNIX-Tools auch für Windows; sie heißen dort flex und byacc. Herzlichen Dank noch mal an deepthroat, der mich mal darauf aufmerksam gemacht hat.
    • Es gibt ein Tutorial für lex und yacc bei epaperpress, in dem genau das implementiert wird, was du gemacht hast.
    • Ich verwende als SDK CodeBlocks mit dem mingw.Compiler. Zusätzlich habe ich wxWidgets installiert.
    Geändert von Vereth (12.03.10 um 17:34 Uhr)
    killerkirsche bedankt sich. 
    Vielen Dank für die Nutzung des Bewerten- und Danke-Buttons

    Wenn man sieht, dass man einen anderen glücklich gemacht hat, ist die Welt um zwei glückliche Menschen reicher.

  7. #7
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Ich weiß nicht genau, wie ich mit yacc oder flex umgehen soll, werde mcih aber noch einlesen.
    Aber ich habe den Fehler (der bei openwatcom ein völlig anderer ist als bei dev-cpp) nun um ein malloc eingekreist.
    Was keinen sinn macht ist, dass der Fehler nur in der Rekursion auftritt.
    Außer ich führe die funktion "termcalc" vor einem anderen "termcalc"-Aufruf aus, dann gibts andere fehler
    Das macht noch weniger sinn..
    ich werde mal wxWidgets ausprobieren
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  8. #8
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Ich komm da irgendwie nicht weiter.
    Ich bekomme random errors zu einem random zeitpunkt.
    Ich weiß ehrlich gesagt nicht mehr weiter...
    Das lustige ist, dass die fehler verschieden sind, je nachdem, ob ich es für WIN32 oder DOS16 kompiliere.
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  9. #9
    Avatar von Vereth
    Vereth Vereth ist offline Mitglied Brokat
    Registriert seit
    Nov 2009
    Ort
    Dortmund
    Beiträge
    372
    Dann schau am besten mal nach, ob du den angeforderten Speicher auch korrekt initialisierst. Möglicherweise hast du einen verirrten Pointer. Was geschieht, wenn du calloc statt malloc verwendest? Gibt es dann eine NullPointerException oder ähnliches?
     
    Vielen Dank für die Nutzung des Bewerten- und Danke-Buttons

    Wenn man sieht, dass man einen anderen glücklich gemacht hat, ist die Welt um zwei glückliche Menschen reicher.

  10. #10
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Ersteinmal danke für deine geduld xD

    soweit ich weiß hat C keine exceptions.
    und calloc macht keinen unterschied (wäre ja noch noch seltsamer =))
    ich werde den code jetzt nach c++ portieten und mit exceptions arbeiten.

    ich meld mich
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  11. #11
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.
    Zitat Zitat von killerkirsche Beitrag anzeigen
    Problem dahingegen gelöst, dass ich DEV-Cpp langsam (datei für datei) gelöscht habe, denn mit openwatcom gibts 0 probleme.
    Wie kann man nur nen compiler vertreiben, der so nen mist macht....
    The Pragmatic Programmer Tip #26: "select" Isn't Broken.
    It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.


    Du hast einige Fehler im Code. Mal ganz abgesehen von Speicherlecks.

    Du reservierst nicht genug Speicher für czTerm2 und schreibst in irgendwelchen Speicherbereichen die du nicht alloziert hast. => undefiniertes Verhalten

    Du terminierst den String czNumber nicht (strncpy terminiert den String nicht immer siehe z.B. http://www.cplusplus.com/reference/c...tring/strncpy/) und liest in nicht allozierten Speicherbereichen. => undefiniertes Verhalten

    Du greifst auf (eigentlich) leere Stacks zu. (die enthalten bei dir zwar mind. ein Element, welches aber nicht initialisiert ist). => undefiniertes Verhalten

    Gruß

    PS: Außerdem ist dein Code zu kompliziert. Du solltest einfacheren Code schreiben. Und du mußt eigentlich nicht x-mal durch den String iterieren brauchst eigentlich auch keine Rekursion.
    Geändert von deepthroat (18.03.10 um 12:43 Uhr)
    killerkirsche bedankt sich. 
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  12. #12
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Vielen vielen Dank Deepthroat

    Ich werde mir das zu Herzen nehmen, was du gesagt hast und das Projekt wahrscheinlich nochmal neu aufsetzen.
    Ich poste nochmal, wenn ichs hab

    mfG
    Niklas
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  13. #13
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    So....
    Es hat sehr lange gedauert (aufgrund einer motivationsschwächen und anderen Projekten), doch nun ist es fertig.
    Ich habe nochmal von vorne angefangen und da explizit darauf geachtet, genug RAM zu allozieren und ihn auch wieder frei zu geben

    Bei mir klappt es einwandfrei, doch ich wäre euch sehr verbunden, dass, wenn ihr die Muße dazu habt, mich auf Fehler hinzuweisen.

    Ich poste hier mal den Quellcode:
    Code c:
    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
    
    /*main.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "termcalc.h"
     
    int main(int argc, char *args[]){
      int i;
      char *szString = "AH";
      for(i=0;i<argc;i++){
        printf("%2i:%s\n",i,args[i]);
      }
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 - 3 - 4",&i));
      printf("%lf\n",calcString("2 ^ 2",&i));
      printf("%lf\n",calcString("-1 + 2 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) ) ^ 2",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) )",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) )",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) )",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) )",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) ) * 1 + 4 * -1",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) ) * 2 + 4 * -1",&i));
      printf("%lf\n",calcString("1 + 2 + 3 + 4 * 2 - 3 + 4 * ( 1 - 2 - ( 2 * 3 ) ) * 3 + 4 * -1",&i));
      i = strlen(szString);
      printf("\n!%s hat %i Zeichen!\n",szString,i);
      system("PAUSE");
      return EXIT_SUCCESS;
    }
    Code c:
    1
    2
    3
    4
    5
    6
    
    /*termcalc.h*/
     
    #ifndef TERMCALC_H
      #define TERMCALC_H
      double calcString( char *szTermIn , int *nError);
    #endif /* -- TERMCALC.H ------ */
    Code c:
    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
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    
    /*termcalc.c*/
      #include <string.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <math.h>
      #define bool unsigned char
      #define true  1
      #define false 0
      #define maybe 2
     
     
    struct sElement{
      double dbValue;              //This contains the value of the element if the element isn't a
                                   //operator
      char   chOperator;           //This char has many functions:
                                   //If it is == 0     (ATTENTION: 0 not '0') the element is a number
                                   //If it is == 'e'   There are no mor element
                                   //If it is == 'f'   There is a failure in the term
    };
     
    struct sTerm{
      char *szTerm;                //In this string we will save the term we will calculate
      int   nNextElementPosition;  //This is the position were we can reed the next element of the term in the string
                                   //It is very important that this var is set bye "calcString"
    };
     
    //Deklaration of the funktions:
    double calcString( char *szTermIn , int *nError);
    double calcTerm( struct sTerm *sTmInput , int *nError);
    double calc(double dbValue1,double dbValue2,char chOperator);
    bool   isLowerOperator( char chO1 , char chO2 );
    struct sElement *getNextElement(struct sTerm *sTmInput,struct sElement *sElReturn);
    int    operatorToNumber(char chOp);
     
    /**
     * Calculates two numbers (double)
     * @param  dbValue1   The first number/value
     * @param  dbValue2   The second number/value
     * @param  chOperator The operator (*+/-^)
     * @return            The value we calculated
     */
    double calc(double dbValue1,double dbValue2,char chOperator){
      double dbReturn = 0.0;
      
      switch(chOperator){
        case '*': dbReturn = dbValue1 * dbValue2;
                  break;
        case '+': dbReturn = dbValue1 + dbValue2;
                  break;
        case '/': dbReturn = dbValue1 / dbValue2;
                  break;
        case '-': dbReturn = dbValue1 - dbValue2;
                  break;
        case '^': dbReturn = pow(dbValue1,dbValue2);
                  break;
        default: //There cannot be any inpur-errors because the values and the operator
                 //have been checked several times
                 break;
      }
     
      return dbReturn;
    };/*--double calc(double dbValue1,double dbValue2,char chOperator)------*/
     
     
    /**
     * PArses a char containing a operator to the mathematical priority of this operator
     * @param  chOp The char containing the mathematical operator
     * @return      The priority of the char as a number:
     *                6=Highest priority
     *                1=Lowest priority
     */    
    int operatorToNumber(char chOp){
      //The operator-list:
      //  6: (             highest priority
      //  5: ^
      //  4: * /
      //  3: -
      //  2: + 
      //  1: )             lowest priority
      //The input oprator will get a number between 1 and 5
      //If the operator is no operator this function returns 'f'
      switch(chOp){
        case '(': return 6;
        case '^': return 5;
        case '*': return 4;
        case '/': return 4;
        case '-': return 3;
        case '+': return 2;
        case ')': return 1;
        default: return 'f';
      }/*--switch(chOp)------*/
    }/*--int operatorToNumber(char chOp)------*/
     
     
    /**
     * Tests if chO1 has a lower priority than chO2
     * @param  chO1 Operator one (which can have the lower priority)
     * @param  chO2 Operator two
     * @return      true is priority is lower
     */
    bool isLowerOperator(char chO1, char chO2){
      //The operator-list:
      //  6: (             highest priority
      //  5: ^
      //  4: * /
      //  3: -
      //  2: +
      //  1: )             lowest priority
        if(chO1==')'){
          //If the first operator is a ')' is has to have the lowest priority because
          //there are not closed brackets on the operator stack
            return true;
        }/*--if(chO1==')')------*/
        if(chO1=='('){
          //If the first operator is a '(' it has to have the highest priority because
          //if there are two open brackets on the stack following each other I do not
          //have to calculate something.
            return false;
        }/*--if(chO1=='(')------*/
        if(chO2=='('){
          //We have to exclude '(' otherwise the will calc with a bracket.
            return false;
        }
     
      //Now the Operators will be parsed to numbers
        chO1=operatorToNumber(chO1);
        chO2=operatorToNumber(chO2);
     
      //Then we have to check if there were errors:
        if(chO1=='f' || chO2=='f'){
          //There was a error so return "maybe"
            return maybe;
        }
     
      //If there were no errors we can test if chO1 has a less priority than chO2
        if(chO1<chO2){
          //chO1 has a lower priority than chO2
            return true;
        }
        else{
          //chO1 is at least as important as chO2
            return false;
        }
    }/*--bool isLowerOperator(char chO1, char chO2)------*/
     
    /**
     * Returns the next element in a sTerm
     * Return-value not neccessary
     * @param  *sTmInput  pointer to the term
     * @param  *sElReturn pointer to the struct which will contain the new information
     * @return            pointer to the struct which will contain the new information
     */
    struct sElement *getNextElement(struct sTerm *sTmInput,struct sElement *sElReturn){
      //Declaration of variables:
        //Numbers    
          int i;                             //The counter of the for-loop
          int nPartLength=1;                 //The length of the current element (min. 1)
        //Chars and strings
          char ch;                           //The current char checked by the for-loop
          char *szNumber;                    //In this char * a dec number will be saved (copied out of czTerm)
     
      //Before we can walk through the term, we have to check if there are any
      //more elements or if the string has ended.
        if((*sTmInput).nNextElementPosition >= strlen((*sTmInput).szTerm)){
          (*sElReturn).dbValue = 0;
          (*sElReturn).chOperator = 'e';   //This 'e' shows the function which
                                           //receive this struct, that there are no
                                           //more elements.
          //Function ends here.
          return sElReturn;
        }/*--if((*sTmInput).nNextElementPosition >= strlen((*sTmInput).czTerm))------*/
     
      //Searching the end of the element
        for(i=(*sTmInput).nNextElementPosition;i<strlen((*sTmInput).szTerm);i++){
          //At first we get the char at position i  
            ch = *((*sTmInput).szTerm+i);                            
          //Checking wether the element has ended now
            if(ch==' '){
              //It has ended
              ch = *((*sTmInput).szTerm+i-1); //correcting the char
              break;
            }
          //It has not ended yet => Go on until it ends
          //The part becomes bigger if it is no operator     
          nPartLength++;
         
        }/*--for(i=(*sTmInput).nNextElementPosition;i<strlen((*sTmInput).czTerm);i++)------*/
       
      //Identifying the element
      //Because ch was the last char we read we can test it if it is an operator
      //or not
      if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' || ch=='^'){
        //It is a operator
        (*sElReturn).dbValue    = 0.0;
        (*sElReturn).chOperator = ch;
      }/*--if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' )------*/
      else{
        //It is no operator, it is an operand
        //Getting the containing string
          szNumber = (char *)calloc((nPartLength+1),sizeof(char));
     
        //Copying the string for parsing it into a double
        strncpy(szNumber,(*sTmInput).szTerm + (*sTmInput).nNextElementPosition,nPartLength);
        (*sElReturn).dbValue    = strtod(szNumber,NULL);  //Parsing the string to
                                                          //a double
        (*sElReturn).chOperator = 0; //when chOperator == 0 the program knows that
                                     //it is a number
        //Preventing memory-leaks
          free(szNumber);
      }/*--if(ch=='+' || ch=='-' || ch=='/' || ch=='*' || ch=='?' || ch==')' || ch=='(' ) else ------*/
      //Next time we want to go a part further 
      (*sTmInput).nNextElementPosition += nPartLength;
     
      return sElReturn;
    }/*--struct sElement *getNextElement(struct sTerm *sTmInput,struct sElement *sElReturn)------*/
     
    /**
     * Calculates a string
     * @param  *szTermIn    The input string which will be calculated
     * @param  *nError      A pointer to a int which will contain the ErrorLevel
     *                        Errorlevels are:
     *                          0:   No errors detected
     *                          1:   Error in term / wrong term
     *                          2:   Too less RAM
     * @return              The value this function calculated
     */
    double calcString(char *szTermIn,int *nError){
        
      //At first the important variables
      char                  *szTermOut;          //This string will be calculated. It is a modified version of szTermIn
      int                    nLengthIn;          //length of the  input-string (szTermIn)
      int                    nLengthOut;         //length of the output-string (szTermOut)
      double                 dbReturn;           //The value which will be returned
      struct sTerm           sTmCalc;            //The term we will calculate
      int                    i,j;                //Just two numbers for for-loops
     
     
      //Getting the length of input string (szTermIn)  
        nLengthIn = strlen(szTermIn);
     
      //Now we have the information of the input string (szTermIn) and we are able
      //to allocate RAM for the output string (szTermOut)
        //It has the length of the input string plus 2 times 2 chars, because we
        //want to add "( " at the beginning and " )" at the end. And we need one
        //additional char for '\0';
        nLengthOut = nLengthIn + 2 * 2 + 1;
        //Allocating the RAM
        szTermOut = (char *)calloc(nLengthOut,sizeof(char));
        //And setting it to '\0'
        memset(szTermOut,'\0',nLengthOut*sizeof(char));
     
      //After allocating the RAM we can copy the input string (szTermIn) into it
        //"( " at the beginning
        strncpy(szTermOut,"( ",2);
        //The input string in the middle
        strncat(szTermOut,szTermIn,nLengthIn);
        //And ' )' at the end
        strncat(szTermOut," )",2);
        //We do not need to add any '\0' because we've done that before
     
      //There is still one problem:
        //because we run backwards through the term a '-' would behave live a "- (".
        //Because of this we have to replace each '-' by a "+ -1 *"
        for(i=0;i<nLengthOut;i++){
          //With this if we check if it is something like "9 + -9" or "9 - 9"
          if(szTermOut[i]=='-' && szTermOut[i+1]==' '){
            //"+ -1 *" is 5 chars longer than '-'
              nLengthOut = nLengthOut + 5;
            //Then we have to reallocate new RAM
              szTermOut = (char *)realloc(szTermOut,nLengthOut * sizeof(char));
            //Then we insert the new string
              //But it needs some space
                for(j=nLengthOut-1;j>i;j--){
                  szTermOut[j]=szTermOut[j-5];
                }
              //Then we can add it
                szTermOut[i++]  ='+';
                szTermOut[i++]=' ';
                szTermOut[i++]='-';
                szTermOut[i++]='1';
                szTermOut[i++]=' ';
                szTermOut[i++]='*';
          }
        }
        
      //Creating the struct we will calculate
        sTmCalc.szTerm               = szTermOut;
        sTmCalc.nNextElementPosition = 0;
     
      //Calculating the struct
      dbReturn = calcTerm(&sTmCalc,nError);
     
      //Free memory
        free(szTermOut);
     
      
     
      //Return value
      return dbReturn;
    }/*--double calcString(char *szTermIn)------*/
     
     
    /**
     * Calculates a sTerm.
     * @param  *sTmInput      pointer to the input struct.
     * @param  *nError        pointer to a int. This int will contain the errorlevel of this function.
     *                        Errorlevels are:
     *                          0:   No errors detected
     *                          1:   Error in term / wrong term
     *                          2:   Too less RAM
     * @return                Calculated value of the input sTerm struct
     */
    double calcTerm(struct sTerm *sTmInput,int *nError){
        struct sElement sElElement;
        double dbReturn;
     
        int  nOperandStackSize  = 0;
        int  nOperatorStackSize = 0;
        bool bCalc              = false;
        bool bExit              = false;
     
        double dbValue;
     
        //We are using two stacks: one for operators and one for operands
        //(operators are "+-/*()" and operands are numbers)
          double *dbaOperandStack;      //Stack for Operands
          char   *chaOperatorStack;     //Stack for Operators
        //We have to initialize them:
          dbaOperandStack   = (double *)calloc(nOperandStackSize +1,sizeof(double));  //min. 1 operator
          chaOperatorStack  = (char   *)calloc(nOperatorStackSize+1,sizeof(double));  //min. 1 operator
        //And of cause check the stacks
          if(dbaOperandStack==NULL || chaOperatorStack==NULL){
            //We cannot allocate enough memory so return errorlevel 2
            free(dbaOperandStack);
            free(chaOperatorStack);
            (*nError)=2;
            return 0.0;
          }
     
        
        //To get this whil loop running we have to set the sElElement.chOperator
        sElElement.chOperator='w';
     
        while(sElElement.chOperator!='e'){
          //Getting the next element
          getNextElement(sTmInput,&sElElement);
          //=======================================================================================================================;
          //Check the element
          //=======================================================================================================================;
            if(sElElement.chOperator==0){
              //The operator-char is 0 so it has to be a number
                //The Stack grows so the size has to grow, too
                  nOperandStackSize++;
                //Reallocating the memory  
                  dbaOperandStack = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
               //And of cause check the stacks
                 if(dbaOperandStack==NULL || chaOperatorStack==NULL){
                   //We cannot allocate enough memory so return errorlevel 2
                    free(dbaOperandStack);
                    free(chaOperatorStack);               
                   (*nError)=2;
                   return 0.0;
                 }
                 
                //Pushing new value on the stack
                  dbaOperandStack[nOperandStackSize-1] = sElElement.dbValue;
            }/*--if(sElElement.chOperator==0)------*/
            else{
              //It can be an operator or 'e'/'f'
              if(sElElement.chOperator=='e'){
                //The term has ended
                  //We do not have to calculate something because there was a ')' before ending so everything is calculated already
                    bCalc = false;
                  //But we do have to exit
                    bExit = true;
                  
              }/*--if(sElElement.chOperator=='e')------*/
              else if(sElElement.chOperator=='f'){
                //There is a failure in the term so we exit at this point and set the error
                  (*nError)=1;
                  //Before we can quit we have to free all allocated RAM
                    free(dbaOperandStack);
                    free(chaOperatorStack);
                  return 0.0;
              }/*--else if(sElElement.chOperator=='f')------*/
              else{
                //It has to be an operator.
                  bCalc = maybe;
     
              }/*--if(sElElement.chOperator=='e') else------*/
            }/*--if(sElElement.chOperator==0) else------*/
          
          //=======================================================================================================================;
          //Calculate      
          //=======================================================================================================================;
            if(bCalc==maybe){
              //We will only calc something, if the new operator has a less priotity than the last
              //operator which has been pushed on the stack. If the new operator is only the second
              //one we wont calc, as well, because the first is a open bracket. We cannot calc a
              //bracket
              if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1]) && nOperatorStackSize >= 2){
                //It has a lower priority, so calc!
                  bCalc=true;
              }/*--if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1]) && nOperatorStackSize >= 2)------*/
              else{
                //We do not need to calculate something
                  bCalc=false;
                //But we have to push the operator on the stack
                  nOperatorStackSize++;
                  chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));
               //And of cause check the stacks
                 if(dbaOperandStack==NULL || chaOperatorStack==NULL){
                   //We cannot allocate enough memory so return errorlevel 2
                    free(dbaOperandStack);
                    free(chaOperatorStack);               
                   (*nError)=2;
                   return 0.0;
                 }
                  chaOperatorStack[nOperatorStackSize-1]=sElElement.chOperator;
              }/*--if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1]) && nOperatorStackSize >= 2) else------*/
            }/*--if(bCalc==maybe)------*/
            if(bExit){
              //If bExit==true we do not have to calculate something because there has been a ')' before the end
              //But we have to set the error level and return a Value
                (*nError) = 0;
                dbReturn = dbaOperandStack[0];
                bCalc = false;
            }/*--if(bExit)------*/
            //Now we checked everything so we can calculate something
              while(bCalc==true){
                //This loop is diveded in two parts:
                //1. Calculate something
                //2. Check if we need to calculate something again
                
                //1. Calc
                  dbValue = calc(dbaOperandStack[nOperandStackSize-2],dbaOperandStack[nOperandStackSize-1],chaOperatorStack[nOperatorStackSize-1]);
                  dbaOperandStack[nOperandStackSize-2]=dbValue;
                  //We "used" one operand and on operator so we have to decrement the size
                    nOperatorStackSize--;
                    nOperandStackSize--;
                  //And of cause we have to reallocate RAM because we do not need as much as before
                    dbaOperandStack  = (double *)realloc(dbaOperandStack,nOperandStackSize*sizeof(double));
                    chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));
                 //And of cause check the stacks
                   if(dbaOperandStack==NULL || chaOperatorStack==NULL){
                     //We cannot allocate enough memory so return errorlevel 2
                      free(dbaOperandStack);
                      free(chaOperatorStack);               
                     (*nError)=2;
                     return 0.0;
                   }
                  
                //2. Check if calc another one
                  //When we check if we have to calc another element we have to look for two thing:
                    //2.1. Is the current one ')' and the one before '('
                      //Then we have to delete the open bracket and calc no nother one
                    //2.2. If not does the current one still have a lower priority than the one before
                      //Then we have to calc another
                      //Else we have to push the operand on the stack
     
                  //2.1
                    if(chaOperatorStack[nOperatorStackSize-1]=='(' && sElElement.chOperator== ')'){
                      //They are two matching brackets
                        nOperatorStackSize--;
                        chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));
                      //And of cause check the stacks
                        if((dbaOperandStack==NULL || chaOperatorStack==NULL ) && nOperatorStackSize>0){
                          //We cannot allocate enough memory so return errorlevel 2
                            free(dbaOperandStack);
                            free(chaOperatorStack);               
                            (*nError)=2;
                            return 0.0;
                        } 
                        bCalc=false;
                    }/*--if(chaOperatorStack[nOperatorStackSize-1]=='(' && sElElement.chOperator== ')')------*/
                  //2.2
                    else{
                      //They aren't matching brackets
                        if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1])){
                          //It has a lower priority, so calc!
                            bCalc=true;
                        }/*--if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1])------*/
                        else{
                          //We do not need to calculate something
                            bCalc=false;
                          //But we have to push the operator on the stack
                            nOperatorStackSize++;
                            chaOperatorStack = (char *)realloc(chaOperatorStack,nOperatorStackSize*sizeof(char));
                           //And of cause check the stacks
                             if(dbaOperandStack==NULL || chaOperatorStack==NULL){
                               //We cannot allocate enough memory so return errorlevel 2
                               free(dbaOperandStack);
                               free(chaOperatorStack);               
                               (*nError)=2;
                               return 0.0;
                             }
                            chaOperatorStack[nOperatorStackSize-1]=sElElement.chOperator;
                        }/*--if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1]) else------*/
                        
                    }/*-if(chaOperatorStack[nOperatorStackSize-1]=='(' && sElElement.chOperator== ')') else------*/
                    
              }/*--while(bCalc)------*/
              
     
        }/*--while(sElElement.chOperator!='e')------*/
       
     
        free(dbaOperandStack);
        free(chaOperatorStack);
        
        //Setting error-level to 0
        (*nError)=0;
        return dbReturn;
        
    }/*--double calcTerm(struct sTerm *sTmInput,int *nError)------*/
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

  14. #14
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.

    Speicherlecks sehe ich jetzt keine mehr, aber du greifst wieder auf ein Arrayelement zu welches nicht existiert => undefiniertes Verhalten.

    Code c:
    1
    
    if(isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1]) && nOperatorStackSize >= 2){
    Du greifst hier schon auf den Stack zu und schaust danach ob der Index überhaupt valide ist. Das mußt du umgekehrt machen:
    Code c:
    1
    
    if(nOperatorStackSize >= 2 && isLowerOperator(sElElement.chOperator,chaOperatorStack[nOperatorStackSize-1])){
    Gruß

    PS: Es gibt kein Format %lf bei printf.
    PPS: Warum muss man denn Leerzeichen zwischen die Operanden/Operatoren schreiben?
    Geändert von deepthroat (22.04.10 um 20:10 Uhr)
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  15. #15
    Avatar von killerkirsche
    killerkirsche killerkirsche ist offline Mitglied Gold
    Registriert seit
    Jan 2008
    Beiträge
    168
    Ok,
    Dickes Danke dafür.
    Ihr habt mit einen großen Gefallen getan.
    mfG,
    Niklas
     
    die ärzte | Wizo | Patti Smith
    Wer die nich kennt der verpasst was

Ähnliche Themen

  1. Gleichungen Lösen
    Von Nord-Süd-Richtung im Forum Coders Talk
    Antworten: 4
    Letzter Beitrag: 01.12.09, 15:48
  2. Antworten: 4
    Letzter Beitrag: 04.02.08, 00:26
  3. Mathe: Lösen von lin. Gleichungen in C#? Gauß?
    Von xaitech im Forum .NET Café
    Antworten: 4
    Letzter Beitrag: 06.02.06, 14:02
  4. HI Solver Problem
    Von s4w im Forum 3D Studio Max
    Antworten: 2
    Letzter Beitrag: 27.05.05, 12:59
  5. HI SOLVER und die Knickstelle
    Von goreafk im Forum 3D Studio Max
    Antworten: 0
    Letzter Beitrag: 03.07.04, 13:12

Stichworte