You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言argp库如何将-u、-w命令行选项设置为必填项

C语言argp库必填选项校验实现方案

问题描述

使用C语言argp库开发命令行工具时,需要将-u(--url)和-w(--wordlist)两个选项设置为必填项:用户未传入任意一个参数时自动输出错误提示,两个参数必须同时提供程序才可以正常运行,网上未检索到同类问题的现成解决方案。

初始错误实现

最初将参数校验逻辑写在parse_opt函数的选项处理分支之后,即使在main函数中完成了参数结构体初始化,该校验代码始终无法触发,相关代码如下:

argp.c

#include "../header/argp.h"

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

const char *argp_program_version = "WiBreak 0.0.1";
static char doc[] = "Program used to brute force URL.";
static char args_doc[] = "[-u URL] [-w WORDLIST]";
static struct argp_option options[] = {
    {"url", 'u', "URL_TO_QUERY", 0, "Compare lines instead of characters."},
    {"wordlist", 'w', "WORDLIST", 0, "Compare words instead of characters."},
    {"verbose", 'v', 0, OPTION_ARG_OPTIONAL, "Show more info"},
    {0}};


// TODO: Need to handle when no argument are given.
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
    struct arguments *arguments = state->input;
    int *arg_cout = state->input;
    switch (key) {
        case 'u':
            arguments->url_to_query = arg;
            // printf("arg : %s\n", arg);
            break;
        case 'w':
            arguments->wordlist = arg;
            break;
        case 'v':
            arguments->verbose = 1;
            break;
        default:
            // argp_usage(state);
            return ARGP_ERR_UNKNOWN;
    }
    // Code never reach even when i initialyze arguments in the main.
    if (arguments->wordlist == "" || arguments->url_to_query == ""){
        argp_failure(state, 1, 0, "too few arguments");
        exit(ARGP_ERR_UNKNOWN);
    }
    
    return 0;
}

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

argp.h

#ifndef __ARGP__H
#define __ARGP__H
#include <argp.h>
#include <stdbool.h>

// static error_t parse_opt(int key, char *arg, struct argp_state *state)
extern struct argp argp;

struct arguments {
    // enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode;
    char *wordlist;
    char *url_to_query;
    bool verbose;
    // bool isCaseInsensitive;
};
#endif

main.c

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

    // arguments.mode = CHARACTER_MODE;
    // arguments.isCaseInsensitive = false;
    arguments.wordlist = "";
    arguments.url_to_query = "";

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

    // printf("Wordlist : %s, Url : %s\n", arguments.wordlist,
    // arguments.url_to_query);
    // ...
}

问题原因

parse_opt函数每解析到一个参数就会被触发一次,写在switch分支后的校验逻辑只有在解析到u/w/v三个选项时才会执行,此时另一个必填参数大概率还没完成解析,自然无法实现两个参数都填完后的校验逻辑。另外代码中用==比较字符串指针的写法也存在逻辑问题,无法正确判断空字符串。

最终解决方案

在parse_opt函数的switch分支中新增ARGP_KEY_END处理逻辑,该key会在所有参数全部解析完成后触发,此时再做必填项校验即可生效,修改后的代码片段如下:

case ARGP_KEY_END:
            // printf("arguments->wordlist : %s, arguments->url_to_query : %s\n", arguments->wordlist, arguments->url_to_query);
            if (arguments->wordlist == NULL || arguments->url_to_query == NULL){
                argp_failure(state, 1, 0, "required -u and -w. See --help for more information");
                exit(ARGP_ERR_UNKNOWN);
            }

注意:使用该逻辑时需要将main函数中参数结构体的初始化值从空字符串""改为NULL,和校验逻辑的判断条件保持一致。


内容的提问来源于stack exchange,提问作者RaiZy_Style

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 05:24:02