繁体   English   中英

在C中解析可选的命令行参数

[英]Parsing optional command line arguments in C

我有一个接受可选参数的程序。 必要的参数是文件和整数(1或更多)。 可选参数是字符串和整数的混合。

因此,命令行上的正确输入可能是:

./main trace_file 8 12 # (only necessary arguments)

./main –n 3000000 –p page.txt trace_file 8 7 4 # (with optional arguments)

我需要将trace_file之后的整数转换为数组。 在启用可选参数时,我无法弄清楚如何执行此操作,因为命令行上有另一个整数。 推进正确的方向将非常感激,因为我无法弄清楚如何做到这一点。

编辑:到目前为止,解析参数的所有内容是:

for(j=2, k=0; j<argc; j++, k++) {
    shift += atoi(argv[j]);
    shiftArr[k] = 32 - shift;
    bitMaskArr[k] = (int)(pow(2, atoi(argv[j])) - 1) << (shiftArr[k]);
    entryCnt[k] = (int)pow(2, atoi(argv[j]));
}

但这只有在没有输入可选参数时才有效。

如果你使用合理的POSIX兼容版本的getopt()我没有看到任何重大问题。

源代码( goo.c

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

/*
   ./main trace_file 8 12 # (only necessary arguments)

   ./main –n 3000000 –p page.txt trace_file 8 7 4 # (with optional arguments)
 */

static void usage(const char *argv0)
{
    fprintf(stderr, "Usage: %s [-n number][-p pagefile] trace n1 n2 ...\n", argv0);
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    int number = 0;
    char *pagefile = "default.txt";
    char *tracefile;
    int opt;

    while ((opt = getopt(argc, argv, "n:p:")) != -1)
    {
        switch (opt)
        {
        case 'p':
            pagefile = optarg;
            break;
        case 'n':
            number = atoi(optarg);
            break;
        default:
            usage(argv[0]);
        }
    }

    if (argc - optind < 3)
    {
        fprintf(stderr, "%s: too few arguments\n", argv[0]);
        usage(argv[0]);
    }

    tracefile = argv[optind++];
    printf("Trace file: %s\n", tracefile);
    printf("Page file:  %s\n", pagefile);
    printf("Multiplier: %d\n", number);
    for (int i = optind; i < argc; i++)
        printf("Processing number: %d (%s)\n", atoi(argv[i]), argv[i]);
    return 0;
}

汇编

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>      -Wold-style-definition -Werror goo.c -o goo

示例运行

$ ./goo trace_file 8 12
Trace file: trace_file
Page file:  default.txt
Multiplier: 0
Processing number: 8 (8)
Processing number: 12 (12)
$ ./goo -n 3000000 -p page.txt trace_file 8 7 4
Trace file: trace_file
Page file:  page.txt
Multiplier: 3000000
Processing number: 8 (8)
Processing number: 7 (7)
Processing number: 4 (4)
$

我已经给了这个想法,并且没有简单的方法让getopt返回多个参数。 我确实想知道定义“y ::”,但已经驳回了这一点。 选项是

1)有两个选项y和Y使用一个每个int和一个布尔标志来捕获定义y的异常,但Y不是。

2)在getopt循环中留下y之类的复杂选项。 一旦getopt处理了选项和洗牌参数。 预处理这些参数以捕获-y操作数和进程参数中的代码以跳过-y及其操作数

3)在* nix命令中更常见的是将多个值作为单个参数提供,该参数本身是逗号分隔的值列表。 您可以通过在getopt处理中添加“y:”来实现此目的。 它指向的字符串也需要从字符串A,B解析为2个令牌A和B.

如果你不能使用getopt()或其他一些为你努力工作的函数,那么可能的策略是:

  • 创建新的变量myargc,myargv,并将argc和argv复制到它们中。

  • 编写与配对的参数(如“-n 300000”或“-p page.txt”处理功能。传递myargc,并通过引用 myargv到这些功能。每一个这样的函数返回的参数(例如,300000页关联的值。 txt)如果找到了,或者是无效值(例如,-1或“”),如果不是。在任何一种情况下,该函数都会从myargv中删除这两个项目并将myargc减少2。

  • 如果你的参数只是单独的标志,那么为那些返回boolean指示是否找到该标志的函数写函数,从myargv中删除标志,并将myargc递减1.(你可以用这种方式处理trace_file,即使它不是我假设trace_file只是一个标志,与之后的8不相关。

  • 首先调用每个可选参数的函数。 在你调用它们之后留在myargc和myargv中的东西应该只是你需要的参数,你可以像往常一样处理它们。

如果你不能使用getopt()或其他一些为你努力工作的函数,那么可能的策略是:

创建新的变量myargc,myargv,并将argc和argv复制到它们中。

编写处理配对参数的函数(如“-n 300000”或“-p page.txt”。通过引用将myargc和myargv传递给这些函数。每个这样的函数返回与参数关联的值(例如,300000或页面)。 txt)如果找到了,或者是无效值(例如,-1或“”),如果不是。在任何一种情况下,该函数都会从myargv中删除这两个项目并将myargc减少2。

如果你的参数只是单独的标志,那么为那些返回boolean指示是否找到该标志的函数写函数,从myargv中删除标志,并将myargc递减1.(你可以用这种方式处理trace_file,即使它不是我假设trace_file只是一个标志,与之后的8不相关。)

首先调用每个可选参数的函数。

暂无
暂无

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

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