【问题标题】:Using Scanf to read in an equation of random length使用 Scanf 读取随机长度方程
【发布时间】:2014-03-03 14:49:29
【问题描述】:

我试图读入一个方程,然后分别取每个部分,然后用户可以输入任意大小的方程(例如 3+7、2+-9+8 甚至 2)。我有这个,但它似乎没有工作。

printf("Please enter an equation\n");

scanf("%f", &num);
//printf("%f", num);


while ( num != '\n'){
scanf("%f", &num);
scanf("%c", &op);
//printf("%c  %f \n", op, num);
}

当我输出我得到的东西时,它与输入不同。

【问题讨论】:

  • 使用fgets(),然后用char解析char这一行。

标签: c scanf


【解决方案1】:

您可能希望阅读How to read a line from the console in C? 了解完整的详细信息,但基本上您只需这样做:

char * getline(void) {
    char * line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;

    if(line == NULL)
        return NULL;

    for(;;) {
        c = fgetc(stdin);
        if(c == EOF)
            break;

        if(--len == 0) {
            len = lenmax;
            char * linen = realloc(linep, lenmax *= 2);

            if(linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}

【讨论】:

    【解决方案2】:

    您正试图在浮点变量(代码中的数字)中获取完整的表达式。如果您在 while 循环中执行 scanf("%f", &num);,那么您只是覆盖了 num 中的值。您需要在 char 数组或 char* 中获取表达式。然后你需要一个算法来分离运算符和数字,将数字转换为所需的类型并求解。

    【讨论】:

      【解决方案3】:

      如果你想阅读一个表达式并让你的程序理解它,你需要非常重的机器。要么这是XY problem,即您需要重新考虑问题并找到另一种方法;或者您应该查看整个解析/编译区域。

      脚本语言(如 Python 或 Perl)具有某种 eval 内置功能,因此您可以将代码的 sn-p 作为文本并对其进行评估(运行)。也许使用其中之一更适合您的问题?但请注意,盲目运行用户输入的任何内容都会带来巨大风险......

      【讨论】:

        【解决方案4】:

        要使用 scanf 读取任意长度的行,您可以使用

        scanf("%[^\n]", equation);
        

        这个正则表达式的意思是“阅读所有内容,直到找到 '\n' 字符”。 请记住,这并不安全,因为用户很容易溢出“方程式”缓冲区。如果您想避免这种情况,我建议您在一个循环中逐个字符地读取字符,如下所示:

        for(i=0; i < MAX_EQ_SIZE; i++)
        {
            char tmp;
            scanf("%c", &tmp);
            if(tmp == '\n') 
                break;
            equation[i] = tmp;
        }
        

        由于您只是询问如何阅读,我不打算解析阅读方程式。 这是一个代码示例:

        #include <stdio.h>
        
        #define MAX_EQ_SIZE 1024
        
        void parse(char * eq) 
        {
            // Do the processing
        }
        
        int main()
        {
            char equation[MAX_EQ_SIZE];
            scanf("%[^\n]", equation); // Read a whole line
            scanf("%*c"); // Read and ignore the \n
        
            puts(equation);
        
            parse(equation);
        }
        

        【讨论】:

          【解决方案5】:

          使用fgets() 读取输入行。
          使用来自sscanf() 的返回值来确定是数字还是运算符。

          int Eval(void) {
            char buffer[100];
            char *p = buffer;
            printf("Please enter an equation\n");
            if (fgets(buffer, sizeof buffer, stdin) == NULL)
              return -1;  // no more input
          
            float num;
            char op;
            int n;
          
            while (*p) {
              if (sscanf(p, "%f %n", &num, &n) == 1) {
                printf("num %f\n", num);
                p += n;
              }
              if (sscanf(p, " %c %n", &op, &n) == 1) {
                printf("op %c\n", op);
                p += n;
              } else if (*p) {
                printf("Error '%s'\n", p);
                return 0;
              }
            }
            return 1;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-04
            • 1970-01-01
            • 1970-01-01
            • 2012-05-16
            • 2023-03-13
            • 1970-01-01
            • 2020-12-19
            相关资源
            最近更新 更多