前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编程小知识之命令行解析

编程小知识之命令行解析

作者头像
用户2615200
发布2018-08-02 17:41:53
2930
发布2018-08-02 17:41:53
举报

当前的软件开发中,图形界面已然大行其道,命令行似乎愈加式微,不过在一些场景下,命令行仍然必不可少~

工具链的正常运作往往需要仰仗命令行,各个工具间的“沟通交流”基本都是通过命令行来完成,考虑一下 C 语言中 main 函数的标准定义:

代码语言:javascript
复制
// C
int main(int argc, char* argv[])
{
    // codes ...

    return EXIT_SUCCESS
}

其中的 argc 便是命令行的参数个数, 而 argv 则是各个具体的命令行参数~

当我们编写支持命令行的程序时,很多时候都不太在意用以解析命令行的相关逻辑,往往随手写些分支代码便了事了,就像这样(以 C# 代码举例):

代码语言:javascript
复制
// C#
public static void Main(string[] args)
{
    if (args.Length > 0)
    {
        if (args[0] == "-a0")
        {
            OnArg0();
        }
        else if (args[0] == "-a1")
        {
            OnArg1(Convert.ToInt32(args[1]));
        }

        // other situations here ...
    }
}

代码很简单,但其中的问题也很明显:

1. 无法处理复合的命令行参数,譬如 “-a0 -a1 100”
2. 处理非字符串参数较为繁琐,代码中需要在各处书写转换逻辑
3. 各种异常难以处理,譬如转换失败、参数错误等等

复合命令行参数的问题我们可以使用循环来解决:

代码语言:javascript
复制
// C#
public static void Main(string[] args)
{
    int index = 0;
    while (index < args.Length)
    {
        if (args[index] == "-a0")
        {
            OnArg0();
            ++index;
        }
        else if (args[index] == "-a1")
        {
            OnArg1(Convert.ToInt32(args[index + 1]));
            index += 2;
        }
        else
        {
            ++index;
        }

        // other situations here ...
    }
}

但是对于另外两个问题我们还要继续寻找解决方法~

其实解析命令行的更好方式还是使用通用逻辑单独处理,而不要使其耦合于业务逻辑之中,为此我们可以编写一个类库,封装相关解析逻辑~

秉持”最小化”接口原则,对于这个命令行解析库,我个人觉得至少要提供下面3个接口:

代码语言:javascript
复制
// add argument handler
void Add(string name, Action handler);

// remove argument handler
void Remove(string name);

// handle arguments
void Handle(string[] args);

Add接口用于添加某个命令行参数的处理函数

Remove接口则用于去除某个命令行参数的处理函数

Handle接口则是进行实际的命令行解析操作,并执行对应的命令行处理函数

有时候我们可能需要解析原始字符串,而不是分割好的参数列表,为此我们可以提供一个重载的Handle接口:

代码语言:javascript
复制
// handle raw arguments
void Handle(string rawArgs);

github上自己简单搞了一个解析库SimpleArgument,有兴趣的朋友可以看看,欢迎 pr ~

有了辅助库,命令行解析便不再恼人了,之前的代码我们可以改写成这样:

代码语言:javascript
复制
// C#
public static void Main(string[] args)
{
    var sa = new SimpleArgument();
    sa.Add("-a0", OnArg0);
    sa.Add<int>("-a1", OnArg1);

    sa.Handle(args);
    // or we can parse raw args directly
    //sa.Handle("-a0 -a1 100");
}

代码简洁明了,比起之前那些交织的分支(循环)要好上不少~

编程已经足够复杂了,一些机械的、枯燥的(往往也是容易出错的)逻辑就交给类库(或者说自动化)去解决吧~

注 : 点击这里了解SimpleArgument

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年07月13日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 无法处理复合的命令行参数,譬如 “-a0 -a1 100”
  • 2. 处理非字符串参数较为繁琐,代码中需要在各处书写转换逻辑
  • 3. 各种异常难以处理,譬如转换失败、参数错误等等
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档