【问题标题】:Read expression using fgets and get the numeric values using sscanf使用 fgets 读取表达式并使用 sscanf 获取数值
【发布时间】:2016-05-27 12:20:14
【问题描述】:

我必须编写一个程序来读取 RPN(反向波兰表示法)表达式,然后对其进行评估。

为了阅读表达式,我必须使用 fgets。然后为了得到这个表达式的数值,我必须使用 sscanf。输入和输出将使用 STDIN 和 STDOUT 完成。

我们的想法是阅读类似的内容:

5 2 pi cos - 4 * + 3 -

然后将此表达式保存到m x 2 矩阵中。

我可以读取数字(无论是否为浮点数)、常量(如pi)、运算符(如+ or - or /)或函数(如sin or cos)。

当我阅读表达式的每个字符时,我必须将此信息存储到矩阵中,如果我有一个数字,我会将其设置在位置 matrix[0][k], where k is not important,如果我有常量,它将位于该位置matrix[1][k], k is not importantmatrix[2][k], k is not important 中的运算符和matrix[3][k] 中的函数。

所以之前的表达式会是这样的:

{{0,5},{0,2},{1,0},{3,2},{2,1},{0,4},{2,2},{2,0},{0,3},{2,1}}.

我必须在 C 中执行此操作,但我遇到了一些问题。主要问题是获取用户输入的表达式的值。我有这个:

int main() {

// Cadena de caracteres donde guardamos la expresion rpn
char str[MAX];

int matrix[MAX][2];
int i = 0; 

printf("Enter a string: ");
// Cogemos los 100 caracteres que haya por consola, controlando errores
if(fgets(str, 100, stdin) == NULL) printf("Error leyendo por consola");

/* Si hay un salto de linea lo borramos */
i = strlen(str)-1;
if( str[ i ] == '\n') str[i] = '\0';

converteix_codis(matrix, str, i);

// Creamos la pila
pila p;
// Inicializamos la pila
initStack(&p);

int a = avalua_rpn(matrix, &p);

// Comprobar si se ha podido evaluar el rpn o no
printf("avalua = %d\n", a);

printf("This is your string: %s\n", str);

return 0;   
}


void converteix_codis(int matriu[MAX][2], char str[MAX], int i)
{
    int tamanyo = 0;

int j, k = 0;
int nombres = 0, constants = 0, operacions = 0, funcions = 0; 
char a[3] = "";
for(j = 0; j < i; ++j) {
    // Si el caracter que leemos es un digito
    if(isdigit(str[j])) {
        matriu[0][nombres] = (int) str[j];
        ++nombres;
        ++tamanyo;
    }
    // Si el caracter que leemos es una operacion
    else if(ispunct(str[j])) {
        int num;
        if(str[j] == '+') num = 0;
        else if(str[j] == '-') num = 1;
        else if(str[j] == '*') num = 2;
        else if(str[j] == '/') num = 3;
        else if(str[j] == '^') num = 4;
        matriu[2][operacions] = num;
        ++operacions;
        ++tamanyo;
    }

}
}

在函数converteix_codis 中,我试图存储此信息,但我不知道如何获取字符串sin, cos, pi, e and others 以将它们存储到矩阵中。使用操作和数字我试过了,但如果我有一个浮点数,它就不会读好。关于如何使用 fgets 和 sscanf 阅读本文有什么建议吗? (我必须使用它们,因为这是一个要求)。

非常感谢!

【问题讨论】:

  • 使用整数而不是字符串。例如,#define SIN 1 并存储 SIN 而不是 sin 字符串
  • 问题是输入必须是那个5 2 pi cos - 4 * + 3 -,因为输入的是用户
  • 我的意思是,读完sin后我存储的值是0,而不是sin值,但首先我必须读sin字符串,你明白吗?
  • 您应该了解外部表示(sincospi 等)和存储的数据不必相同。您应该存储可能的字符串(函数和常量名称)的代码,但将它们作为字符串读取和打印。
  • 我应该只使用 fgets 来读取用户的输入。 sscanf 获取输入的数值,strcmp 获取无数值。

标签: c fgets scanf


【解决方案1】:

拆分和数值决策的示例(简单的方法,而不是严格的方法)。

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

bool isNumber(const char *str, double *num){
    char *endp;
    double n = strtod(str, &endp);
    if(*endp == '\0'){
        *num = n;
        return true;
    }
    *num = NAN;
    return false;
}

int main(void){
    char str[] = "5 2 pi cos - 4 * + 3 -";
    char *token;
    double n;

    token = strtok(str, " \t\n");
    while(token){
        if(isNumber(token, &n)){//if(1==sscanf(token, "%lf%c", &n, &ch)){//char ch;
            printf("%g\n", n);
        } else {
            printf("%s\n", token);
        }
        token = strtok(NULL, " \t\n");
    }
    return 0;
}

【讨论】:

  • 要求使用sscanf
  • if(isNumber(token)){ sscanf(token, "%lf", &amp;n); printf("%g\n", n);
  • 什么是可笑的?
【解决方案2】:

您可以使用fgets 来像您一样读取操作,然后使用sscanf 和辅助指针来将给定的字符串划分为他的元素。它看起来像这样

            #include <stdio.h>
            #include <string.h>
            void main(){
                char str[100];
                char str2[100];

                char * aux; 

                int i, counter, len;
                printf("Introduce operation: ");
                fgets(str,100,stdin);
                strtok(str, "\n"); // Eliminate line jump
                len = strlen(str);
                for (i =0 ,counter =0; i<len ; i++)
                    if (str[i] == ' ') counter ++;  

                aux = str;
                for (i=0; i<counter + 1 ; i++){
                    sscanf(aux, "%s", str2);
                    printf("Element: %s" , str2);
                    aux = str + strlen(str2)* sizeof(char);
                }


            }

这里不包括解析。还可以进行一些改进(例如,为了消除第一个循环)。此代码的目的主要是让您了解如何使用sscanf

编辑:如果需要消除空格:

aux = str + (strlen(str2) + 1) * sizeof(char)

【讨论】:

  • aux = str + strlen(str2)* sizeof(char); : 不考虑空格字符。
  • str + strlen(str2):位置没有继续。
  • 最后一个没看懂。能说清楚一点吗?
  • @BLUEPIXY 有什么想法吗?
  • @MohamedSaidBenmousa 使用strtok
猜你喜欢
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 2021-11-09
  • 1970-01-01
相关资源
最近更新 更多