在 C 中使用 getopt 处理冒号分隔的选项,如 FFmpeg

问题描述 投票:0回答:1

我正在尝试实现类似于 FFmpeg 的选项处理。具体来说,我想支持两种类型的调色板选项:

  • 直接调色板规格:

    -p "255,0,0 0,255,0"

  • 配置文件调色板:

    -p:c blackwhite

与 FFmpeg 处理编解码器选项的方式类似:

ffmpeg -i input.mp4 -c:v libx264 -c:a copy output.mp4


目前,我的代码使用 getopt:

static struct option long_options[] = {
    {"palette", required_argument, 0, 'p'},
    // other options...
};

int main(int argc, char** argv) {
    while ((c = getopt_long(argc, argv, "p:h", long_options, &option_index)) != -1) {
        switch (c) {
            case 'p': 
                if (optarg[0] == 'c' && optarg[1] == ':') {
                    // This doesn't work as intended - optarg becomes ":c"
                    load_palette_from_config(optarg + 2);
                } else {
                    parse_numeric_palette(optarg);
                }
                break;
        }
    }
}

问题在于,当使用

-p:c blackwhite
时,getopt将
:c
视为
-p
的参数,导致调色板加载失败。 有没有办法使用 getopt 实现这种类似 FFmpeg 的选项处理?

c getopt
1个回答
0
投票

getopt 旨在解析简单的单字符命令行选项。 如果您检查使用更复杂选项的二进制文件的代码,例如 ffmpeg,您将看到它们在不使用 getopt 的情况下传递命令行。

您仍然可以使用 getopt 作为您的案例示例。 当您使用“p:h”时,您必须预期“cmd -p:c foobar”将导致“:c”作为 optarg 返回。 在这种情况下,您必须通过检查 argv[optind] 并在下一次迭代之前增加 opting 来从 arglist 中剥离下一个值。 你的“如果”部分应该看起来像...... if (optarg[0] == ':' && optarg[1] == 'c') { if (!(optind < argc )) panic(BAD_ARGV); if (! valid_color(argv[optind])) panic(BAD_ARGV); load_palette_from_config(argv[optind]); optind++; } else { ...

	
© www.soinside.com 2019 - 2024. All rights reserved.