【问题标题】:Parsing commands shell-like in C在 C 中解析命令类似于 shell
【发布时间】:2012-04-24 02:50:02
【问题描述】:

我想在我的 C(仅 C)程序中解析用户输入命令。示例命令:

add node ID

add arc ID from ID to ID

print

exit

等等。然后我想用 ID 做一些验证并将它们转发给指定的函数。函数和验证当然已经准备好了。都是关于解析和匹配函数的......

我已经用很多 ifs 和 strtoks 做到了,但我确信这不是最好的方法......有什么想法(库)吗?

【问题讨论】:

  • 程序是在使用它的命令行参数,还是在读取键盘或文件? ID 是什么?
  • 我通常使用循环和 if 语句来完成它,我怀疑是否有一个用于处理 shell 命令的库。如果你愿意,也许你可以有一个标识类型命令的第一个字母并使用 switch 语句(-P 是打印,-R 是添加类型命令,-E 是退出,等等)
  • 这不是命令行参数,而是在程序运行时从键盘读取用户命令。类似于 Python 中的“shlex”。
  • 如果你想用 C 实现你自己的 shell,你看过这个相关的问题:stackoverflow.com/q/1500004/1025391 吗?有许多对您有用的链接。
  • 已经尝试过 GNU libreadline? cnswww.cns.cwru.edu/php/chet/readline/rltop.html

标签: c parsing shell command ansi


【解决方案1】:

我认为你想要的是这样的:

while (1) 
{
    char *line = malloc(128); // we need to be able to increase the pointer
    char *origLine = line;
    fgets(line, 128, stdin);

    char command[20];
    sscanf(line, "%20s ", command);

    line = strchr(line, ' ');

    printf("The Command is: %s\n", command);

    unsigned argumentsCount = 0;
    char **arguments = malloc(sizeof(char *));

    while (1)
    {
        char arg[20];
        if (line && (sscanf(++line, "%20s", arg) == 1))
        {
            arguments[argumentsCount] = malloc(sizeof(char) * 20);
            strncpy(arguments[argumentsCount], arg, 20);

            argumentsCount++;

            arguments = realloc(arguments, sizeof(char *) * argumentsCount + 1);
            line = strchr(line, ' ');
        }
        else {
            break;
        }
    }

    for (int i = 0; i < argumentsCount; i++) {
        printf("Argument %i is: %s\n", i, arguments[i]);
    }

    for (int i = 0; i < argumentsCount; i++) {
        free(arguments[i]);
    }

    free(arguments);
    free(origLine);
}  

你可以在释放它之前用“命令”和“参数”做你想做的事。

【讨论】:

  • 也许这不是“完美的世界”,但这或多或少是我需要的:)
【解决方案2】:

这取决于您的命令语言有多复杂。如果您有多个命令,或者如果每个命令可以采用多种形式,例如您的add 命令,则可能值得费心编写一个简单的recursive descent parser。

我过去曾为一些项目手工完成过几个 RDP。这有点工作,但它允许您处理一些相当复杂的命令,否则这些命令将无法直接解析。您也可以使用 lex/yacc 或 flex/bison 之类的解析器生成器,尽管这可能对您正在做的事情来说太过分了。

否则,它基本上就是你所描述的; strok 和一堆嵌套的 if 语句。

【讨论】:

    【解决方案3】:

    我只是想在 Richard Ross 的回复中添加一些内容:检查 malloc 和 realloc 的返回值。这可能会导致您的程序中出现难以发现的崩溃。

    【讨论】:

      【解决方案4】:

      您的所有命令行参数都将存储到名为argv 的字符串数组中。

      您可以使用argv[0]、argv[1] ... argv[n] 访问这些值。

      【讨论】:

      • 我认为他在谈论非命令行命令,即他可能是在告诉用户在程序运行时输入命令来编辑文件或打印程序中的一些数据。
      • 与@YoussefG 完全一样。说。它是实时的。
      • 即便如此,我认为这不值得投反对票 - 含糊不清的问题。
      • @user120115 同意。我最初认为这个问题是关于命令行参数的,直到我读完为止。
      猜你喜欢
      • 2011-12-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      相关资源
      最近更新 更多