【问题标题】:Reverse Polish Calc in C: using argv as a way to store and retrieve resultsC中的逆波兰计算:使用argv作为存储和检索结果的一种方式
【发布时间】:2014-11-22 02:06:29
【问题描述】:

我正在尝试做一个 RPN,其中我的非恒定 argv 向量通过将运算符替换为操作结果来存储和检索计算结果: argv[0]="2"; argv[1]="3"; argv[2]="+" ==> argv[0]="2";argv[1]="3";argv[2]=5 我的代码适用于简单的 RPN 输入——最多一次操作的输入;它在嵌套操作中失败,因为当它读取 argv[n] 时,它没有在其中找到任何内容,因此它认为它为零。 你们能帮忙吗?代码如下:

    /*
    * Ahmed AlJehairan
    * Github: aj326
    * Description: Reverse Polish Calc. Usage ./expr n1 n2 op
    */
    #include <stdio.h>
    #include <stdlib.h>
    #define DEBUG 1
    //Will implement error checking later:
    /*
    Errors to check for:
       arg starts with letter
       first arg not a number
       check at least two arg for binary ops
    */

    int main(int argc, char *argv[])
    {
        char **s = argv;
        int len = argc;
        if (argc < 3)
        {
            printf("At least 2 arguments\n");
            return 1;
        }
    if (--argc)   argv++;

    int val;
    while (argc--)
    {
        switch (**argv)
        {

        case '+': ; val = atoi(*(argv - 2)) + atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        case '=': ; val = atoi(*(argv - 2)) == atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        case '-': ; val = atoi(*(argv - 2)) - atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        case '*': ; val = atoi(*(argv - 2)) * atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        case '/': ; val = atoi(*(argv - 2)) / atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        case '%': ; val = atoi(*(argv - 2)) % atoi(*(argv - 1)); snprintf (*argv, sizeof(int), "%d", val); if (DEBUG) printf("after arith *argv %s \n", *argv); break;
        }
        if (DEBUG)
        {
            int i;
            for (i = 0; i < len; ++i)
            {
                printf("%s\t", s[i]);
            }
            printf("\n");
        }
        argv++;
    }
    printf("%s\n", *--argv);
    return 0;
}

【问题讨论】:

  • 为结果准备另一个转换的数组。
  • 我将简单地指出编写一个在给定无效输入的情况下按设计调用未定义行为的程序是多么可怕。 IE。 + 0 1。更糟糕的是,假设输入是“有效的”,尽管标准允许您将 alternate 地址存储在 0..argc 中的任何 nargv[n]。它没有声称 exiting 地址处的内存是可写的。简而言之,这是一个可怕的想法。使用适当大小的本地 int 堆栈。
  • @WhozCraig 关于“标准允许您将备用地址存储在 argv[n]”参见stackoverflow.com/questions/25737434/is-argvn-writable/25747537 此外,规范明确表示 argv[][] 是可写的,尽管它在该范围内是安静的。
  • @chux 对我来说是新手。我记得(诚然可能不正确),argv 指向的字符串并不总是可修改的,尽管地址 in argv 是可替换的。但是,即使在 OP 的情况下,给定字符串单字符参数 '1' 的大小也不是 sizeof(int)(32 位 = 4 个八位字节)。最多是1可写字符+终止NULL(snprintf的第二个参数应该解释;即2表示1+nullchar,4表示3+nullchar,这显然不适合以前的字符串1+nullchar).

标签: c argv


【解决方案1】:

snprintf (*argv, sizeof(int),... 不一定有效。

它的可用大小肯定不是由sizeof(int) 定义的,并且不应假定比原始strlen(argv[])+1 更多。

打印任意int varies 所需的char 的大小。建议

#define MAXPRINTSIZE (CHAR_BIT*sizeof(int)*10/33 + 3)
char bufer[MAXPRINTSIZE];
snprintf (buffer, sizeof buffer, "%d", val); 

您将不得不重新考虑您的缓冲区管理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2021-11-29
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多