手把手写C++服务器:常用boost之program_options命令行参数解析

Posted 沉迷单车的追风少年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手写C++服务器:常用boost之program_options命令行参数解析相关的知识,希望对你有一定的参考价值。

前言:boost作为C++最重要的扩展库,以其广泛的使用范围,高优的性能,完善的技术氛围,强大的可移植性和开放的源码,是C++编程必不可少的“武器”。手把手写C++服务器这个专题会介绍几个最常用的boost,本篇文章介绍program_options用于命令行参数解析,从常见的argc、argv聊起,一起打开program_options的世界!

目录

int argc, char *argv[]

argc和argv[]含义

举个例子

program_options

优点与官网地址

组件

使用流程

编程范例

编译运行


int argc, char *argv[]

在传递命令行参数的时候,这种写法非常常见:

int main (int argc, char *argv[])

如果不需要传递命令行参数,用void代替没有任何问题。那么,到底这种写法有什么用呢?

argc和argv[]含义

argv 和 argc 是命令行参数在 C 和 C++ 中传递给 main() 的方式。

  • argc:参数计数。命令行总的参数个数+1第一个参数是程序的名称
  • argv:参数向量。向量里面存放命令行具体参数。

注意:这只是一种惯例写法,这些变量被命名为 argc(参数计数)和 argv(参数向量)。但它们可以被赋予任何有效的标识符:int main(int num_args, char** arg_strings) 同样有效。

 

举个例子

vim argv_argc.cpp
#include <iostream>

int main(int argc, char *argv[]) {
    std::cout << "Have" << argc << "arguments:" << std::endl;
    for (int i = 0; i < argc; i++) {
        std::cout << argv[i] << std::endl;
    }
}

编译:

g++ argv_argc.cpp -o argv_argc

运行:

./argv_argc a1 b2 c3 d4
Have 5 arguments:
./argv_argc
a1
b2
c3
d4

如果改成int main (void),就会报编译错误:

g++ argv_argc_void.cpp -o argv_argc_void
argv_argc_void.cpp: In function ‘int main()’:
argv_argc_void.cpp:4:28: error: ‘argc’ was not declared in this scope
     std::cout << "Have" << argc << "arguments:" << std::endl;
                            ^~~~
argv_argc_void.cpp:6:22: error: ‘argv’ was not declared in this scope
         std::cout << argv[i] << std::endl;
                      ^~~~

program_options

优点与官网地址

刚才介绍的argc、argv能够获取命令行参数,但是boost提供了一个更加强大的命令行参数库program_options。program_options的优点如下:

  • 简单易学。
  • 声明选项的语法很简单,而且库本身很小。诸如将选项值转换为所需类型和存储到程序变量之类的事情是自动处理的。
  • 错误报告更好。命令行的所有问题都会报告,而手写代码可能只是错误解析输入。此外,使用消息可以自动生成,以避免与真实的选项列表不同步。

最好的学习方法就是官网手册,这是官网教程的地址:

https://www.boost.org/doc/libs/1_75_0/doc/html/program_options/tutorial.html

组件

组件名作用
options_description(选项描述器)描述当前的程序定义了哪些选项
parse_command_line(选项分析器)解析由命令行输入的参数
variables_map(选项存储器)容器,用于存储解析后的选项

使用流程

1、包含头文件

#include <boost/program_options.hpp>

2、构造命名空间

namespace bpo = boost::program_options;

3、构造选项描述器和选项存储器

bpo::options_description opts("all options");
bpo::variables_map vm;

4、在选项描述器中添加选项

      opts.add_options ()
          ("help,h", "produce help message")
          ("compression,c", bpo::value<int>(), "set compression level")
          ("filename,f", bpo::value<std::string>(), "the file name which want to be found");

5、参数解析&&异常处理

    try {
        bpo::store(bpo::parse_command_line(argc, argv, opts), vm);
    } catch (...) {
        std::cout << "input undecleare options!" << std::endl;
    }

6、判断选项

    if (vm.count("help")) {
        std::cout << opts << std::endl;
    }
    if (vm.count("filename")) {
        // 取出后的类型是boost::any,需要通过模板成员函数as<type>()做类型转换,才能获取具体值
        std::cout << "find: " << vm["filename"].as<std::string>() << std::endl;
    }
    if (vm.empty()) {
        std::cout << "input is empty!" << std::endl;
    }

编程范例

#include <iostream>
#include <boost/program_options.hpp>
#include <string>

int main (int argc, char *argv[]) {
    // 步骤一:构造命名空间
    namespace bpo = boost::program_options;

    // 步骤二:构造选项描述器
    bpo::options_description opts("all options");
    // 步骤二:构造选项存储器,用法和map类似
    bpo::variables_map vm;

    // 步骤三:为选项描述器添加选项
    opts.add_options ()
        ("help,h", "produce help message")
        ("compression,c", bpo::value<int>(), "set compression level")
        ("filename,f", bpo::value<std::string>(), "the file name which want to be found");

    // 步骤四:对命令行输入参数做解析,并存入选项存储器中
    // 捕获异常
    try {
        bpo::store(bpo::parse_command_line(argc, argv, opts), vm);
    } catch (...) {
        std::cout << "input undecleare options!" << std::endl;
    }

    // 步骤五:notify更新所有外部变量
    bpo::notify(vm);

    // 步骤六:对解析完的参数处理
    // count用来判断在选项存储器中是否存在这个选项
    if (vm.count("help")) {
        std::cout << opts << std::endl;
    }
    if (vm.count("filename")) {
        // 取出后的类型是boost::any,需要通过模板成员函数as<type>()做类型转换,才能获取具体值
        std::cout << "find: " << vm["filename"].as<std::string>() << std::endl;
    }
    if (vm.empty()) {
        std::cout << "input is empty!" << std::endl;
    }

    return 0;
}

编译运行

编译时候记得加上 -lboost_program_options

g++ boost_program_options.cpp -o boost_program_options -lboost_program_options

运行:

./boost_program_options -h
all options:
  -h [ --help ]            produce help message
  -c [ --compression ] arg set compression level
  -f [ --filename ] arg    the file name which want to be found
./boost_program_options -f=boost_program_options
find: =boost_program_options
./boost_program_options -f
input undecleare options!
input is empty!

 参考:

以上是关于手把手写C++服务器:常用boost之program_options命令行参数解析的主要内容,如果未能解决你的问题,请参考以下文章

手把手写C++服务器(10):结构体struct常用技术之柔性数组字节对齐__attribute__

手把手写C++服务器(19):序列化数据网络传输解决方案

手把手写C++服务器(27):五大文件描述符零拷贝控制总结

手把手写C++服务器(33):Linux常用命令合集

手把手写C++服务器(25):万物皆可文件之socket fd

手把手写C++服务器(32):三大事件之信号详解