尝试将数字字符串转换为float时使用atof()和strtod()时出错

时间:2016-03-30 16:07:20

标签: c stack type-conversion postfix-notation

我已经制作了代码,用后缀表示法(RPN)从文件中读取表达式并输出值。虽然正确读取值并显示没有任何使用小数位数的表达式的输出,但对于包含浮点值的任何表达式,它都默认为error。

基本上,如果在从文件读取的字符串中找到数字,则需要将其转换为浮点数。

我已经不成功地尝试将数据值设置为等于atof(str)和strtod(const char * str,char ** endptr),但我仍然收到错误。

这是我的代码:

#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;
}
}

文件中有5个后缀表达式,它们如下:

 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 /

但是,程序的输出会拒绝第三个表达式,因为它包含10.33,这不是整数值。

输出:

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

有谁知道如何修改此代码来处理浮动?

干杯。

1 个答案:

答案 0 :(得分:0)

您可以尝试手动处理十进制值,几乎与处理整数相同,但在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);
        }
        ...

但实际上strtod为你做了......:

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);
        }
        ...