栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言中命令行参数处理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言中命令行参数处理

文章目录
    • 应用场景
    • 实践
    • 相关链接
    • 其他代码

应用场景

命令行参数有不同的样式。

# 短选项与长选项
ls -a # 短线后面跟选项,选项没有参数
ls -alh # 不带参数的选项可用连写,不分先后顺序
ls --all # 双短线的长选项,和-a是相同的功能

# 选项后面是否跟参数
ls -a # 不带参数
ls --block-size=SIZE # 带参数
ls --color[=WHEN] # 参数可选,选项和参数之间没有空格

ls使用getopt_long()函数实现上面功能。

static struct option const long_options[] =
{
  {"all", no_argument, NULL, 'a'},
  {"escape", no_argument, NULL, 'b'},
  ...
  {"context", no_argument, 0, 'Z'},
  {"author", no_argument, NULL, AUTHOR_OPTION},
  {GETOPT_HELP_OPTION_DECL},
  {GETOPT_VERSION_OPTION_DECL},
  {NULL, 0, NULL, 0}
};

int c = getopt_long (argc, argv,"abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1",long_options, &oi);

可以看到命令行选项有两种样式(两者等价):long_options[]和"abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1"。

long_options[]使用的option结构体如下:

struct option
{
  const char *name; // 长选项名
  int has_arg; // 选项是否带参数:不带参数,带参数,参数可选
  int *flag;   // 当flag等于NULL,getopt_long返回val
  int val;     // val 可以设置成长选项名的第一个字母
};

长选项转换成短选项。

const char *optstring_from_long_options(const struct option *opt){
    // 将长参数转换成短参数
    // "AB:C::"表示:A后面没有参数;B后面有参数;C后面可以有参数,也可以没有,有的话必须紧跟选项
    static char optstring[256] = {0};
    char *osp = optstring;

    for(; opt->name != NULL; opt++){
        if(opt->flag == 0 && opt->val >= 'A' && opt->val <= 'z'){
            *osp++ = opt->val;
            switch (opt->has_arg){
            case optional_argument:
                *osp++ = ':';
                *osp++ = ':';
                break;
            case required_argument:
                *osp++ = ':';
                break;
            default:
                break;
            }
        }
    }

    return optstring;
}
实践

下面的代码改自fuzznetlink.c。

需求:打印文字情感logo。

  • 一个选项(无参数),用以确定情感文字类型。
  • 一个选项(带参数),用以确定打印一类情感文字的个数。
  • 一个选项(可选参数),不带参数时随机打印一个情感文字,带参数时打印指定个数的情感文字。
➜  tree        
.
├── comm.h
├── logo.cpp
├── long_options.cpp
└── Makefile

0 directories, 4 files

其他代码见仓库。下面为命令行参数处理代码。

#include 
#include 
#include 
#include 

#include "comm.h"

using namespace std;

struct state {
    int smile_nums=0;
    int cry_nums=0;
    int tired_nums=0;
    int nums=0;
    int kinds = 3;
};

static void usage(const char *command){
    // C语言中连续的用""引起的字符串常量,会默认合并为一个常量字符串
    fprintf(stderr,
    "Usage:n"
    "n"
    "   %s [option]n"
    "n"
    "Options;n"
    "n"
    "   -s --smile        Print smile logon"
    "   -c --cry          Print cry logon"
    "   -t --tired        Print tired logon"
    "   -n --nums         nums logos are printedn"
    "   -r --rand         rand(choice) output logon"
    "n",
    command);
}

const char *optstring_from_long_options(const struct option *opt){
    // 将长参数转换成短参数
    // "AB:C::"表示:A后面没有参数;B后面有参数;C后面可以有参数,也可以没有,有的话必须紧跟选项
    static char optstring[256] = {0};
    char *osp = optstring;

    for(; opt->name != NULL; opt++){
        if(opt->flag == 0 && opt->val >= 'A' && opt->val <= 'z'){
            *osp++ = opt->val;
            switch (opt->has_arg){
            case optional_argument:
                *osp++ = ':';
                *osp++ = ':';
                break;
            case required_argument:
                *osp++ = ':';
                break;
            default:
                break;
            }
        }
    }

    return optstring;
}

int main(int argc, char **argv){
    static struct option long_options[] = {
        {"smile",no_argument,NULL,'s'},
        {"cry",no_argument,NULL,'c'},
        {"tired",no_argument,NULL,'t'},
        {"nums",required_argument,NULL,'n'},
        {"rand",optional_argument,NULL,'r'},
        {NULL,0,0,0}
    };

    const char *optstring = optstring_from_long_options(long_options);

    struct state st;
    int i=0, n=0;

    while(1){
        int option_index = 0;
        int arg = getopt_long(argc,argv,optstring,long_options,&option_index);

        if(arg == -1)
            break;
        
        switch (arg){
        case 0:
            fprintf(stderr,"Unknow option :%s", long_options[option_index].name);
            exit(-1);
            break;
        case 's':
            st.smile_nums = 1;
            break;
        case 'c':
            st.cry_nums = 1;
            break;
        case 't':
            st.tired_nums = 1;
            break;
        case 'n':
            st.nums = atoi(optarg);
            break;
        case 'r':
            // 随机生成optarg个相同的表情
            if(optarg)
                n = atoi(optarg);
            else
                n = 1;
            srand(time(NULL));
            i = rand()%st.kinds;
            if(i == 0)
                st.smile_nums = n;
            else if(i == 1)
                st.cry_nums = n;
            else
                st.tired_nums = n;
            break;
        default:
            fprintf(stderr,"Unknow option :%s", long_options[option_index].name);
            exit(-1);
            break;
        }
    }

    if(st.nums != 0){
        if(st.smile_nums) st.smile_nums = st.nums;
        if(st.cry_nums) st.cry_nums = st.nums;
        if(st.tired_nums) st.tired_nums = st.nums;
    }


    // 根据读取的参数,绘制表情
    for(int i=0; i 

执行结果如下:

./long_options --tired
  _   _              _ 
 | | (_)            | |
 | |_ _ _ __ ___  __| |
 | __| | '__/ _ / _` |
 | |_| | | |  __/ (_| |
  __|_|_|  ___|__,_|
                       

./long_options -c -n 2
                  
  / __| '__| | | |
 | (__| |  | |_| |
  ___|_|   __, |
             __/ |
            |___/ 
                  
                  
  / __| '__| | | |
 | (__| |  | |_| |
  ___|_|   __, |
             __/ |
            |___/ 


./long_options -r2    
                _ _      
               (_) |     
  ___ _ __ ___  _| | ___ 
 / __| '_ ` _ | | |/ _ 
 __  | | | | | | |  __/
 |___/_| |_| |_|_|_|___|
                         
                         
                _ _      
               (_) |     
  ___ _ __ ___  _| | ___ 
 / __| '_ ` _ | | |/ _ 
 __  | | | | | | |  __/
 |___/_| |_| |_|_|_|___|


 ./long_options -st
                _ _      
               (_) |     
  ___ _ __ ___  _| | ___ 
 / __| '_ ` _ | | |/ _ 
 __  | | | | | | |  __/
 |___/_| |_| |_|_|_|___|
                         
                         
  _   _              _ 
 | | (_)            | |
 | |_ _ _ __ ___  __| |
 | __| | '__/ _ / _` |
 | |_| | | |  __/ (_| |
  __|_|_|  ___|__,_|
                       
                       
相关链接

getopt(3) — Linux manual page

Linux下getopt_long函数的使用

其他代码

头文件:comm.h

#ifndef COMM_H
#define COMM_H

#include 
#include 
#include 

// logo相关的变量声明和函数
extern const std::vector smile_str;
extern const std::vector cry_str;
extern const std::vector tired_nums;
void print_logo(const std::vector &logo);

#endif

logo相关函数和数据结构。

#include 
#include 
#include 

#include "comm.h"

const std::vector smile_str = {
    "                _ _      ",
    "               (_) |     ",
    "  ___ _ __ ___  _| | ___ ",
    " / __| '_ ` _ \| | |/ _ \",
    " \__ \ | | | | | | |  __/",
    " |___/_| |_| |_|_|_|\___|",
    "                         ",
    "                         "
};

const std::vector cry_str = {
    "                  ",
    "  / __| '__| | | |",
    " | (__| |  | |_| |",
    "  \___|_|   \__, |",
    "             __/ |",
    "            |___/ ",
    "                  "
};

const std::vector tired_nums = {
    "  _   _              _ ",
    " | | (_)            | |",
    " | |_ _ _ __ ___  __| |",
    " | __| | '__/ _ \/ _` |",
    " | |_| | | |  __/ (_| |",
    "  \__|_|_|  \___|\__,_|",
    "                       ",
    "                       "
};

void print_logo(const std::vector &logo){
    int n = logo.size();
    for(int i=0; i 

编译过程:makefile

all:long_options

long_options:long_options.cpp logo.cpp
	g++ -o $@ $^ -I .

clean:
	rm -f long_options
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/676015.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号