2016-03-30 2 views
0

Ich habe Code erstellt, um Ausdrücke aus einer Datei in Postfix-Notation (RPN) zu lesen und den Wert auszugeben. Während das Lesen der Werte und das Anzeigen von Ausgaben für Ausdrücke ohne Zahlen, die Dezimalstellen verwenden, korrekt ist, wird für jeden Ausdruck, der einen Gleitkommawert enthält, standardmäßig der Fehler verwendet.Fehler bei der Verwendung von atof() und strtod() beim Konvertieren numerischer Zeichenfolgen in Gleitkomma

Wenn eine Ziffer in einer aus einer Datei gelesenen Zeichenfolge gefunden wird, muss sie im Grunde in eine Gleitkommazahl konvertiert werden.

Ich habe versucht, den Datenwert gleich atof (str) und strtod (const char * str, char ** endptr) zu setzen, aber ich bekomme immer noch den Fehler.

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

int top = -1; 
float stack[500]; 

/* push the given data into the stack */ 
void push (int data) { 
stack[++top] = data; 
} 

/* Pop the top element from the stack */ 
float pop() { 
float data; 
if (top == -1) 
    return -1; 
data = stack[top]; 
stack[top] = 0; 
top--; 
return (data); 
} 

int main() { 

char str[500]; 
FILE *p; 
if((p=fopen("testfile1.txt","r"))==NULL){ 
    printf("\n Unable to open file string.txt"); 
    return 1; 
} 

while(fgets(str,500,p)!='\0'){ 

    float data = -1, operand1, operand2, result; 

    for (int i = 0; i < strlen(str); i++) { 
     if (isdigit(str[i])) { 
      /* 
      * if the i/p char is digit, parse 
      * character by character to get 
      * complete operand 
      */ 
      data = (data == -1) ? 0 : data; 
      data = (data * 10) + (str[i] - 48); 
      continue; 
     } 

     if (data != -1) { 
      /* if the i/p is operand, push it into the stack */ 
      push(data); 
     } 

     if (str[i] == '+' || str[i] == '-' 
       || str[i] == '*' || str[i] == '/') { 
      /* 
      * if the i/p is an operator, pop 2 elements 
      * from the stack and apply the operator 
      */ 
      operand2 = pop(); 
      operand1 = pop(); 
      if (operand1 == -1 || operand2 == -1) 
       break; 
      switch (str[i]) { 
       case '+': 
        result = operand1 + operand2; 
        /* push the result into the stack */ 
        push(result); 
        break; 
       case '-': 
        result = operand1 - operand2; 
        push(result); 
        break; 
       case '*': 
        result = operand1 * operand2; 
        push(result); 
        break; 
       case '/': 
        result = operand1/operand2; 
        push(result); 
        break; 
      } 
     } 
     data = -1; 
    } 
    if (top == 0) 
     printf("Output:%3.2f\n", stack[top]); 
    else 
     printf("have given wrong postfix expression\n"); 
    return 1; 
} 
} 

Es gibt 5 postfix Ausdrücke in der Datei, und sie sind wie folgt:

Hier ist mein Code

13 1 - 2/3 155 + * 
100 100 100 100 + + + 
10.33 2 2 2 2 2 * * * * * 
30 10 - 10 - 10 - 2 * 
300 13.25 - 11 3 -/4 5 - * 3/

Aber bestreitet die Ausgabe des Programms den dritten Ausdruck, weil Es enthält 10.33, was kein ganzzahliger Wert ist.

Ausgang:

Output: 948.00 
Output: 400.00 
have given wrong postfix expression 
Output: 0.00 
Output: 300.00 

Wer weiß, wie dieser Code zu modifizieren Schwimmer zu behandeln?

Prost.

+0

diese Linie in Bezug auf: 'während {', die Funktion (fgets (str, 500, p) = '\ 0'!): 'fgets()' gibt nie ein NUL-Zeichen. Von der Manpage: 'fgets() gibt s bei Erfolg zurück, und NULL bei Fehler oder wenn das Ende der Datei auftritt, während keine Zeichen gelesen wurden.' '' 'Ist der Zeiger, der als erster Parameter übergeben wurde. Schlagen Sie für 'NULL' anstelle von' \ ' – user3629249

+0

in Bezug auf diese Zeile vor: 'if (isdigit (str [i])) {' das kann keinen Gleitkommawert eingeben, weil ein '.' keine Ziffer und ohne ist das '.' ist kein Float-Wert. – user3629249

+0

Die Funktion: 'strtod()' arbeitet mit 'doubles' und' floats' mit: 'strtof()' – user3629249

Antwort

0

Sie könnten versuchen, manuell fast die gleichen Dezimalzahlen verarbeiten Sie ganze Zahlen verarbeiten, aber es wäre einfacher, direkt eine Zahl in einem einzigen Durchgang durchläuft in C:

while(fgets(str, sizeof(str), stdin) != NULL) { 
    unsigned int i; 
    for (i=0; i<strlen(str); i++) { 
     if (isdigit(str[i])) { 
      data = str[i++] - '0'; // initialize data with first digit 
      while(isdigit(str[i])) { 
       data = data * 10 + (str[i++] - '0'); // increment with other digits 
      } 
      if (str[i] == '.') { // decimal part 
       double mult = .1; 
       i++; 
       while(isdigit(str[i])) { 
        data = data + mult * (str[i++] - '0'); // increment with decimal part 
        mult *= .1; 
       } 
      } 
      push(data); 
     } 
     ... 

Aber in der Tat strtod tut es für Sie ...:

while(fgets(str, sizeof(str), stdin) != NULL) { 
    unsigned int i; 
    for (i=0; i<strlen(str); i++) { 
     if (isdigit(str[i])) { 
      char *end; 
      data = ::strtod(str+i, &end); 
      i = end - str; // that's all we are past the number... 
      push(data); 
     } 
     ... 
Verwandte Themen