C语言是如何处理命令行参数的?


原文地址:C语言是如何处理命令行参数的?

本篇文章记录一下C语言是如何处理命令行参数的。一个是Getopt库,一个是Argp库。推荐使用Getopt,因为该库是跨平台的。

今天突发无意中产生了一个疑问?MySQL是如何解析SQL语句的,然后在网上找答案的时候找着找着看到的C语言。好吧,那就记录一下C语言是如何解析命令行参数的,毕竟我对命令行开发也是很兴趣的。

通过查阅资料得知,C语言解析命令行参数一共有三种方法:

  • Getopt#include <unistd.h>来自POSIX C库),可以解决简单的参数解析任务。例如知名的bash Shell解析命令参数用的就是内置的getop(t基于GNU libc中的Getopt)。
  • Argp#include <argp.h>来自GNU C库),它可以解决更复杂的任务并处理诸如以下内容:
    • -?--help以获取帮助消息,包括电子邮件地址
    • -V--version有关版本信息
    • --usage对于使用消息
  • 自己动手做,一般不建议自己动手做,因为出错的可能性太大,Getopt在PHP中也有该函数,看来先把php玩熟练了再玩C的Getopt也不迟。

GNU C库文档为Getopt和Argp提供了一些不错的示例。一般情况下,C库的官方文档示例都很详尽:

同时这里也贴几个从stackoverflow上复制来的示例:

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

int main(int argc, char *argv[])
{
    bool isCaseInsensitive = false;
    int opt;
    enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode = CHARACTER_MODE;

    while ((opt = getopt(argc, argv, "ilw")) != -1) {
        switch (opt) {
        case 'i': isCaseInsensitive = true; break;
        case 'l': mode = LINE_MODE; break;
        case 'w': mode = WORD_MODE; break;
        default:
            fprintf(stderr, "Usage: %s [-ilw] [file...]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    // Now optind (declared extern int by <unistd.h>) is the index of the first non-option argument.
    // If it is >= argc, there were no non-option arguments.

    // ...
}

Argp的解析参数的示例

#include <argp.h>
#include <stdbool.h>

const char *argp_program_version = "programname programversion";
const char *argp_program_bug_address = "<your@email.address>";
static char doc[] = "Your program description.";
static char args_doc[] = "[FILENAME]...";
static struct argp_option options[] = { 
    { "line", 'l', 0, 0, "Compare lines instead of characters."},
    { "word", 'w', 0, 0, "Compare words instead of characters."},
    { "nocase", 'i', 0, 0, "Compare case insensitive instead of case sensitive."},
    { 0 } 
};

struct arguments {
    enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode;
    bool isCaseInsensitive;
};

static error_t parse_opt(int key, char *arg, struct argp_state *state) {
    struct arguments *arguments = state->input;
    switch (key) {
    case 'l': arguments->mode = LINE_MODE; break;
    case 'w': arguments->mode = WORD_MODE; break;
    case 'i': arguments->isCaseInsensitive = true; break;
    case ARGP_KEY_ARG: return 0;
    default: return ARGP_ERR_UNKNOWN;
    }   
    return 0;
}

static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };

int main(int argc, char *argv[])
{
    struct arguments arguments;

    arguments.mode = CHARACTER_MODE;
    arguments.isCaseInsensitive = false;

    argp_parse(&argp, argc, argv, 0, 0, &arguments);

    // ...
}

C语言解析参数推荐使用Getopt

Argp是不是标准的化glibc API扩展(不太懂什么意思),总之使用Getopt就行了,因为Getopt是跨平台的,在MacOS上也同样可以使用,而Argp就不行。

评论

登录后评论

服务器优惠活动

Top