繁体   English   中英

如何从 C 中的用户输入中检索三个变量

[英]How can I retrieve three variables from a user input in C

我需要为学校制作一个小型计算器,使用以下模板: "operation(operator1, operator2)" 例如: "Add(1, 2)"将返回3"Multiply(2, 5)"将返回10 我知道我可以使用strtok来检索操作,但我不确定如何检索运算符。 目前我有以下内容:

#include <stdio.h>
int main()
    {
        char Math_Input[32]; //This is where I will store the input in the following template: operation("operator1, operator2")
        float Operator_1, Operator_2;

        printf("What calculation do you wish to do?: ");
        fgets(Math_Input,20,stdin); //Here I retrieve the entire line and I'll store it in Math_Operation, next step is to retrieve the operation, operator1 and operator2

        char * Math_Operation = strtok(Math_Input, "(");

        printf("%s\n", Math_Operation);

    }

更新:

在给出了一些使用 sscanf() 的代码后,我将代码修改为以下内容:


#include <stdio.h>
int main()
    {
        char Math_Input[32]; //This is where I will store the input in the following template: operation("operator1, operator2")
        char Math_operation[16];
        float Operator_1, Operator_2;

        printf("What calculation do you wish to do?: ");
        fgets(Math_Input,20,stdin); //Here I retrieve the entire line and I'll store it in Math_Input, next step is to retrieve the operation, operator1 and operator2
        if (3 != sscanf(Math_Input, "%15s (%f ,%f )", Math_operation, &Operator_1, &Operator_2)) {
            fprintf(stderr, "Incorrect line >%s<\n", Math_Input);
                printf("Operation: %s \n", Math_operation);
                printf("Operator1: %d \n", Operator_1);
                printf("Operator2: %d \n", Operator_2);
            }
        else {
                // Ok process the operation...
                printf("Else");
                printf("Operation: %s \n", Math_operation);
                printf("Operator1: %d \n", Operator_1);
                printf("Operator2: %d \n", Operator_2);
            }

    }

我使用了一些 printf 来调试。 这在理论上应该有效吗? 但是当我像这样测试它时:(所以这是我的控制台)它似乎不起作用......

What calculation do you wish to do?: Add(1, 2)
Incorrect line >Add(1, 2)
<
Operation: Add(1,
Operator1: 0
Operator2: 0

Process returned 0 (0x0)   execution time : 3.698 s
Press any key to continue.

如果期望输入格式为operation(value_1, value2) ,那么它看起来像是sscanf的正确用例。 据说scanf家族是穷人的解析器,因为它不支持错误恢复。 但是在这里你已经从fgets得到了你的输入行,只需要一个简单的解析。 所以我会使用:

    char Math_Input[32]; //This is where I will store the input in the following template: operation("operator1, operator2")
    char Math_operation[16];
    float Operator_1, Operator_2;

    printf("What calculation do you wish to do?: ");
    fgets(Math_Input,20,stdin); //Here I retrieve the entire line and I'll store it in Math_Operation, next step is to retrieve the operation, operator1 and operator2
    if (3 != sscanf(Math_Input, "%15[^ (] (%f ,%f )", Math_operation, &Operator_1, &Operator_2)) {
        fprintf(stderr, "Incorrect line >%s<\n", Math_input);
    }
    else {
        // Ok process the operation...
    }
    ...

sscanf的好消息是它将忽略任何非有意义的空白字符。

其他改进:确保fgets可以获得完整的行(不超过 19 个字符),否则读取到行尾,您稍后需要循环

正如你在评论中所说:

用户将输入“Add(1,2)”或“Multiply(2,5)”

你可以做你正在做的事情,即标记字符串:

#include <stdio.h>
#include <string.h>

int main()
{
        int data_field = 3;
        char Math_Input[32];
        char* Math_Operation = NULL;
        // operation("operand1,operand2")
        float operand_1, operand_2;

        printf("What calculation do you wish to do?: ");
        scanf("%31[^\n]%*c", Math_Input);

        Math_Operation = strtok(Math_Input, "(");
        while(data_field-- != 0)
        {
                printf("%s\n", Math_Operation);
                if (data_field == 2)
                {
                        Math_Operation = strtok(NULL, ",");
                        sscanf(Math_Operation, "%f", &operand_1);
                }
                if (data_field == 1)
                {
                        Math_Operation = strtok(NULL, ")");
                        sscanf(Math_Operation, "%f", &operand_2);
                }
        }
        return 0;
}

Output:

What calculation do you wish to do?: Add(2,1)
Add
2
1

PS:您可以使用sscanf()存储操作数。

在我看来,最好(也是最有效)的方法是编写一个简单的解析器,如下所示:

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

int
main(void)
{
    char input[32], function_name[32];
    float function_args[2];

    char *iterator, *bufptr, buffer[32];
    /* we will use buffer to temporarily store float,
       and bufptr to store tokens beginning */

    printf("What calculation do you wish to do?: ");
    fgets(input, 20, stdin);

    /* On this step we have input, probably in format `name(val1, val2)`.
       Now we are going to parse this: */

    iterator = input; /* iterator will point to first character of an input */
    bufptr = iterator; /* bufptr will now point to a beginning of a token */
    while (*iterator != '(' && *iterator != '\0')
        ++iterator;

    /* Now iterator points to '(', or string ended because we got
       NULL-terminator, so we will check for a terminator: */

    if (*iterator == '\0') { /* String ended */
        fputs("Syntax error :(", stderr);
        exit(1);
    }

    /* Copying function name to function_name variable.
       We will copy amount of characters equal iterator - input,
       because we added 1 to iterator, so iterator points to '(' now: */

    strncpy(function_name, bufptr, iterator - bufptr);

    /* Now, we are doing exacly the same thing, but now for ','.
       You can surround this loops with a function: */
    ++iterator; /* iterator points to '(', so we will just add 1 */
    bufptr = iterator;
    while (*iterator != ',' && *iterator != '\0') ++iterator;
    if (*iterator == '\0') { /* String ended */
        fputs("Syntax error :(", stderr);
        exit(1);
    }

    strncpy(buffer, bufptr, iterator - bufptr);
    function_args[0] = strtof(buffer, NULL);

    /* Now we can continue parsing, iterator now should point to a comma.
       Doing same thing as upper, but now for ')' */
    ++iterator;
    bufptr = iterator;
    while (*iterator != ')' && *iterator != '\0') ++iterator;
    if (*iterator == '\0') { /* String ended */
        fputs("Syntax error :(", stderr);
        exit(1);
    }

    strncpy(buffer, bufptr, iterator - bufptr);
    function_args[1] = strtof(buffer, NULL);

    while (*iterator != ')' && *iterator != '\0') ++iterator;
    if (*iterator == '\0') { /* String ended */
        fputs("Syntax error :(", stderr);
        exit(1);
    }

    /* Printing */
    printf("Function that you called: %s(%f, %f)\n",
            function_name, function_args[0], function_args[1]);

    /* And on this point you have all expected data, so you can call functions */
    if (!strcmp(function_name, "Add")) {
        Add(function_args[0], function_args[1]);
    } else if (!strcmp(function_name, "Substract")) {
        Substract(function_args[0], function_args[1]);
    } else {
        /* ... */
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM