不只是 [C 语言] :请问各位大佬是如何处理 main 函数传入的参数的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
12tall
V2EX    程序员

不只是 [C 语言] :请问各位大佬是如何处理 main 函数传入的参数的

  •  
  •   12tall 2019-09-24 09:16:56 +08:00 3443 次点击
    这是一个创建于 2277 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请问,如果传入 main 函数的参数较多,应该如何组合处理啊

    /* * demo.exe * 使用:demo.exe -name 12tall -age 12 -boy -newbie */ int main(argc,char* argv[]){ /* * 有一个思路: * 1. 参数分为两种:需要读取值的,例如 -name -age ;不需要读取值的,大胆称为 [状态参数] 吧,例如 -boy -newbie * 2. 一般需要传入值的参数都赋予默认值 * 3. [状态参数] 可以这样取值:-boy=01b、-girl=00b、-newbie=00b、-expert=10b ;这样就可以组成 00b~11b 四种状态 * 4. 然后对应着写 4 个状态处理的函数(参数就是需要取值的那些参数,例如 name、age ),放在一个存放函数指针数组里面,由状态参数组合成的最终值就是指向合适函数的索引 */ } 
    第 1 条附言    2019-09-24 10:15:48 +08:00

    我的表述有问题,应该是:
    鉴于if...else... 嵌套的层数太多不好理解
    请问如何组合程序获取到的参数,以确定接下来的代码怎么走

    第 2 条附言    2019-09-24 18:00:47 +08:00

    写了一个例子,目标是做一个软盘读写的工具。感觉也没有精简太多,不包含解析参数的部分,只有最简单的状态处理
    整体思路是利用宏命令批量声明组合函数,然后再手工实现函数定义,并绑定到一个数组中
    然后程序就可以根据参数通过位掩码直接定位到函数
    但是感觉宏定义那块还是很僵硬!

    // 头文件bin2img.h #ifndef __BIN2IMG__ #define __BIN2IMG__ #define Params const char* fIn,const char* fOut,int offset typedef void (*pStateFunction)(Params); // format #define F_RAW 0b00000000 #define F_FAT12 0b00000001 // boot #define B_NORMAL 0b00000000 #define B_BOOT 0b00010000 // init #define I_NONE 0b00000000 #define I_INIT 0b01000000 // 批量声明函数,共2*2*2=8个 #define GenStateFunctions(_)\ void _(Params); // 磁盘格式 #define FORMAT_LIST(_,$)\ _(F_RAW_##$)\ _(F_FAT12_##$) // 是否是启动盘 #define BOOT_LIST(_,$)\ FORMAT_LIST(_,B_NORMAL_##$)\ FORMAT_LIST(_,B_BOOT_##$) // 初始化还是直接读写 #define INIT_LIST(_)\ BOOT_LIST(_,I_NONE)\ BOOT_LIST(_,I_INIT) INIT_LIST(GenStateFunctions); #undef INIT_LIST #undef BOOT_LIST #undef FORMAT_LIST #undef GenStateFunctions // 给函数指针数组赋值 #define SetStateFunction(index,func)\ funs[index]=func; // 默认帮助函数 void ShowHelp(void); #elif #endif 
    // c 文件 #include <stdio.h> #include <string.h> #include <stdlib.h> #include "bin2img.h" pStateFunction funs[256] = { NULL }; // argc 一般至少为1,因为程序名也会算做参数 int main(int argc, char* argv[]) { // 添加状态函数,这里感觉韩式不够简洁 SetStateFunction(I_INIT, F_RAW_B_NORMAL_I_INIT); // 测试函数 funs[I_INIT](NULL,NULL,0); return 0; } // 函数的实现 void F_RAW_B_NORMAL_I_INIT(const char* fIn, const char* fOut, int offset) { printf("raw normal init"); } void ShowHelp(void) { printf("write binary file to image file or floppy\n"); } 

    收获还是有的~

    23 条回复    2019-09-24 19:22:36 +08:00
    momocraft
        1
    momocraft  
       2019-09-24 09:22:21 +08:00
    学习使用 getopt
    12tall
        2
    12tall  
    OP
       2019-09-24 09:34:05 +08:00
    @momocraft
    我重点表述错了,请问在已经拿到参数的情况下,怎么可以比较好地根据各项参数确定下一步状态,而不要写很多层 if...else...
    pkookp8
        3
    pkookp8  
       2019-09-24 09:46:29 +08:00 via Android
    入参
    设全局变量
    主流程
    if 某个全局变量
    特殊流程
    xpfd
        4
    xpfd  
       2019-09-24 09:55:04 +08:00
    写代码在保证功能的情况下 尽量写的简洁明了, 不用在意行数,反正计算机不费纸,考虑炫技的都是新手,写多了你就道,当年自己挖的坑都得自己埋,写得太隐晦了还没注释,以后自己看都会骂自己蠢
    guyeu
        5
    guyeu  
       2019-09-24 10:11:01 +08:00
    你这个解决方案挺好的呀
    12tall
        6
    12tall  
    OP
       2019-09-24 10:11:10 +08:00
    @pkookp8 @xpfd 但是 if...else...嵌套四五层的话,会眼花缭乱的啊~
    richangfan
        7
    richangfan  
       2019-09-24 10:20:47 +08:00
    设置环境变量
    12tall
        8
    12tall  
    OP
       2019-09-24 10:23:21 +08:00
    @guyeu 谢谢,但还是感觉有点怪怪的,大概是因为没有验证过吧。犹豫就会败北~~~
    12tall
        9
    12tall  
    OP
       2019-09-24 10:24:15 +08:00
    @richangfan 能否详细介绍下,谢谢!
    guyeu
        10
    guyeu  
       2019-09-24 10:27:52 +08:00
    @12tall #8 这种操作叫位掩码,并不是你的独创。。
    shylockhg
        11
    shylockhg  
       2019-09-24 10:30:14 +08:00
    写个结构体,写进结构体里
    12tall
        12
    12tall  
    OP
       2019-09-24 10:34:09 +08:00
    @guyeu 学习了,掩码,谢谢大佬!
    richangfan
        13
    richangfan  
       2019-09-24 10:47:11 +08:00
    @12tall 《 UNIX 环境高级编程》这本操作系统入门书有写
    guyeu
        14
    guyeu  
       2019-09-24 10:52:36 +08:00
    @12tall #12 位掩码,bitmask
    imagecap
        15
    imagecap  
       2019-09-24 10:58:17 +08:00
    定义个参数的 class, 先用 getopt 把参数解析好,让后再根据执行的自己的逻辑代码。
    class arguments
    {
    public:
    bool parse( int argc, char* argv[]) {
    // getop
    }

    public:
    std::string name;
    int age;
    bool sex;
    }



    int main( int argc, char* argv[] )
    {
    arguments args;
    if( !args.parse( argc, argv ) )
    return -1;

    if( args.age > 20 )
    {
    ...
    }
    else
    {

    }


    return 0;
    }
    12tall
        16
    12tall  
    OP
       2019-09-24 11:00:50 +08:00
    @shylockhg @wayixia 谢谢啊!
    skydev
        17
    skydev  
       2019-09-24 11:54:07 +08:00
    用 args.hxx 吧,像 python 的 argsparse 一样。Github 搜一下
    12tall
        18
    12tall  
    OP
       2019-09-24 12:33:05 +08:00
    @skydev 谢谢啦
    xpfd
        19
    xpfd  
       2019-09-24 18:02:39 +08:00
    @12tall 怎么会眼花缭乱? 一个 if 一种情况啊 多简洁明了
    xpfd
        20
    xpfd  
       2019-09-24 18:11:33 +08:00
    你后面的这种写法只适用于 进来的参数都比较统一 变化不大的情况 处理函数的参数也都单一的情况,如果进来的参数五花八门 处理函数返回值 还有参数要求也不一样的情况就难受了
    superalsrk
        21
    superalsrk  
       2019-09-24 18:18:43 +08:00
    同 17L, 几乎每个语言都有类似 argsparse 的东西, 几乎都算是一个标准了
    tommyZZM
        22
    tommyZZM  
       2019-09-24 18:51:53 +08:00
    有解析的库的,引用一下就好了
    类似这种 https://github.com/vietjtnguyen/argagg,C++
    12tall
        23
    12tall  
    OP
       2019-09-24 19:22:36 +08:00
    @xpfd
    @superalsrk
    @tommyZZM

    感谢各位大佬啊,还是自己水平不够吧,第一版就是用的 ifelse 结果把自己绕进去了,还要再继续努力啊
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3157 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:39 PVG 08:39 LAX 16:39 JFK 19:39
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86