1、说明

cmdline是一个轻量级的c++命令行参数解析工具,全部源码只有一个cmdline.h头文件。

2、代码

20171210_命令行进行解析.cpp

// 20171210_命令行进行解析.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cmdline.h"
#include <iostream>

using std::cout;
using std::string;
using std::endl;

int main(int argc, char *argv[])
{
    // 创建一个命令行解析器
    cmdline::parser a;
    // 加入指定类型的输入參数
    // 第一个參数:长名称
    // 第二个參数:短名称(‘\0‘表示没有短名称)
    // 第三个參数:參数描写叙述
    // 第四个參数:bool值,表示该參数是否必须存在(可选。默认值是false)
    // 第五个參数:參数的默认值(可选,当第四个參数为false时该參数有效)
    a.add<string>("host", 'h', "host name", true, "");
    // 第六个參数用来对參数加入额外的限制
    // 这里端口号被限制为必须是1到65535区间的值,通过cmdline::range(1, 65535)进行限制
    a.add<int>("port", 'p', "port number", true, 80, cmdline::range(1, 65535));
    // cmdline::oneof() 能够用来限制參数的可选值
    a.add<string>("type", 't', "protocol type", false, "http", cmdline::oneof<string>("http", "https", "ssh", "ftp"));
    // 也能够定义bool值
    // 通过调用不带类型的add方法
    a.add("gzip", '\0', "gzip when transfer");
    // 执行解析器
    // 仅仅有当全部的參数都有效时他才会返回
    //  假设有无效參数,解析器会输出错误消息。然后退出程序
    // 假设有‘--help‘或-?

    //这种帮助标识被指定,解析器输出帮助信息。然后退出程序
    a.parse_check(argc, argv);
    // 获取输入的參数值
    cout << a.get<string>("type") << "://"
        << a.get<string>("host") << ":"
        << a.get<int>("port") << endl;
    // bool值能够通过调用exsit()方法来推断
    if (a.exist("gzip")) cout << "gzip" << endl;

    return 0;
}

cmdline.h

/*
Copyright (c) 2009, Hideyuki Tanaka
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include <iostream>
#include <sstream>
#include <vector>
#include <map>
#include <string>
#include <stdexcept>
#include <typeinfo>
#include <cstring>
#include <algorithm>
//当编译器非gcc时,不包含cxxabi.h头文件
#ifdef __GNUC__
#include <cxxabi.h>
#endif
#include <cstdlib>

namespace cmdline {

    namespace detail {

        template <typename Target, typename Source, bool Same>
        class lexical_cast_t {
        public:
            static Target cast(const Source &arg) {
                Target ret;
                std::stringstream ss;
                if (!(ss << arg && ss >> ret && ss.eof()))
                    throw std::bad_cast();

                return ret;
            }
        };

        template <typename Target, typename Source>
        class lexical_cast_t<Target, Source, true> {
        public:
            static Target cast(const Source &arg) {
                return arg;
            }
        };

        template <typename Source>
        class lexical_cast_t<std::string, Source, false> {
        public:
            static std::string cast(const Source &arg) {
                std::ostringstream ss;
                ss << arg;
                return ss.str();
            }
        };

        template <typename Target>
        class lexical_cast_t<Target, std::string, false> {
        public:
            static Target cast(const std::string &arg) {
                Target ret;
                std::istringstream ss(arg);
                if (!(ss >> ret && ss.eof()))
                    throw std::bad_cast();
                return ret;
            }
        };

        template <typename T1, typename T2>
        struct is_same {
            static const bool value = false;
        };

        template <typename T>
        struct is_same<T, T> {
            static const bool value = true;
        };

        template<typename Target, typename Source>
        Target lexical_cast(const Source &arg)
        {
            return lexical_cast_t<Target, Source, detail::is_same<Target, Source>::value>::cast(arg);
        }

        static inline std::string demangle(const std::string &name)
        {
#ifdef _MSC_VER
            return name; // 为MSVC编译器时直接返回name
#elif defined(__GNUC__)
            // 为gcc编译器时还调用原来的代码
            int status = 0;
            char *p = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
            std::string ret(p);
            free(p);
            return ret;
#else
            // 其他不支持的编译器需要自己实现这个方法
#error unexpected c complier (msc/gcc), Need to implement this method for demangle
#endif
        }

        template <class T>
        std::string readable_typename()
        {
            return demangle(typeid(T).name());
        }

        template <class T>
        std::string default_value(T def)
        {
            return detail::lexical_cast<std::string>(def);
        }

        template <>
        inline std::string readable_typename<std::string>()
        {
            return "string";
        }

    } // detail

      //-----

    class cmdline_error : public std::exception {
    public:
        cmdline_error(const std::string &msg) : msg(msg) {}
        ~cmdline_error() throw() {}
        const char *what() const throw() { return msg.c_str(); }
    private:
        std::string msg;
    };

    template <class T>
    struct default_reader {
        T operator()(const std::string &str) {
            return detail::lexical_cast<T>(str);
        }
    };

    template <class T>
    struct range_reader {
        range_reader(const T &low, const T &high) : low(low), high(high) {}
        T operator()(const std::string &s) const {
            T ret = default_reader<T>()(s);
            if (!(ret >= low && ret <= high)) throw cmdline::cmdline_error("range_error");
            return ret;
        }
    private:
        T low, high;
    };

    template <class T>
    range_reader<T> range(const T &low, const T &high)
    {
        return range_reader<T>(low, high);
    }

    template <class T>
    struct oneof_reader {
        T operator()(const std::string &s) {
            T ret = default_reader<T>()(s);
            if (std::find(alt.begin(), alt.end(), ret) == alt.end())
                throw cmdline_error("");
            return ret;
        }
        void add(const T &v) { alt.push_back(v); }
    private:
        std::vector<T> alt;
    };

    template <class T>
    oneof_reader<T> oneof(T a1)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        ret.add(a6);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        ret.add(a6);
        ret.add(a7);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        ret.add(a6);
        ret.add(a7);
        ret.add(a8);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        ret.add(a6);
        ret.add(a7);
        ret.add(a8);
        ret.add(a9);
        return ret;
    }

    template <class T>
    oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10)
    {
        oneof_reader<T> ret;
        ret.add(a1);
        ret.add(a2);
        ret.add(a3);
        ret.add(a4);
        ret.add(a5);
        ret.add(a6);
        ret.add(a7);
        ret.add(a8);
        ret.add(a9);
        ret.add(a10);
        return ret;
    }

    //-----

    class parser {
    public:
        parser() {
        }
        ~parser() {
            for (std::map<std::string, option_base*>::iterator p = options.begin();
                p != options.end(); p++)
                delete p->second;
        }

        void add(const std::string &name,
            char short_name = 0,
            const std::string &desc = "") {
            if (options.count(name)) throw cmdline_error("multiple definition: " + name);
            options[name] = new option_without_value(name, short_name, desc);
            ordered.push_back(options[name]);
        }

        template <class T>
        void add(const std::string &name,
            char short_name = 0,
            const std::string &desc = "",
            bool need = true,
            const T def = T()) {
            add(name, short_name, desc, need, def, default_reader<T>());
        }

        template <class T, class F>
        void add(const std::string &name,
            char short_name = 0,
            const std::string &desc = "",
            bool need = true,
            const T def = T(),
            F reader = F()) {
            if (options.count(name)) throw cmdline_error("multiple definition: " + name);
            options[name] = new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
            ordered.push_back(options[name]);
        }

        void footer(const std::string &f) {
            ftr = f;
        }

        void set_program_name(const std::string &name) {
            prog_name = name;
        }

        bool exist(const std::string &name) const {
            if (options.count(name) == 0) throw cmdline_error("there is no flag: --" + name);
            return options.find(name)->second->has_set();
        }

        template <class T>
        const T &get(const std::string &name) const {
            if (options.count(name) == 0) throw cmdline_error("there is no flag: --" + name);
            const option_with_value<T> *p = dynamic_cast<const option_with_value<T>*>(options.find(name)->second);
            if (p == NULL) throw cmdline_error("type mismatch flag '" + name + "'");
            return p->get();
        }

        const std::vector<std::string> &rest() const {
            return others;
        }

        bool parse(const std::string &arg) {
            std::vector<std::string> args;

            std::string buf;
            bool in_quote = false;
            for (std::string::size_type i = 0; i<arg.length(); i++) {
                if (arg[i] == '\"') {
                    in_quote = !in_quote;
                    continue;
                }

                if (arg[i] == ' ' && !in_quote) {
                    args.push_back(buf);
                    buf = "";
                    continue;
                }

                if (arg[i] == '\\') {
                    i++;
                    if (i >= arg.length()) {
                        errors.push_back("unexpected occurrence of '\\' at end of string");
                        return false;
                    }
                }

                buf += arg[i];
            }

            if (in_quote) {
                errors.push_back("quote is not closed");
                return false;
            }

            if (buf.length()>0)
                args.push_back(buf);

            for (size_t i = 0; i<args.size(); i++)
                std::cout << "\"" << args[i] << "\"" << std::endl;

            return parse(args);
        }

        bool parse(const std::vector<std::string> &args) {
            int argc = static_cast<int>(args.size());
            std::vector<const char*> argv(argc);

            for (int i = 0; i<argc; i++)
                argv[i] = args[i].c_str();

            return parse(argc, &argv[0]);
        }

        bool parse(int argc, const char * const argv[]) {
            errors.clear();
            others.clear();

            if (argc<1) {
                errors.push_back("argument number must be longer than 0");
                return false;
            }
            if (prog_name == "")
                prog_name = argv[0];

            std::map<char, std::string> lookup;
            for (std::map<std::string, option_base*>::iterator p = options.begin();
                p != options.end(); p++) {
                if (p->first.length() == 0) continue;
                char initial = p->second->short_name();
                if (initial) {
                    if (lookup.count(initial)>0) {
                        lookup[initial] = "";
                        errors.push_back(std::string("short option '") + initial + "' is ambiguous");
                        return false;
                    }
                    else lookup[initial] = p->first;
                }
            }

            for (int i = 1; i<argc; i++) {
                if (strncmp(argv[i], "--", 2) == 0) {
                    const char *p = strchr(argv[i] + 2, '=');
                    if (p) {
                        std::string name(argv[i] + 2, p);
                        std::string val(p + 1);
                        set_option(name, val);
                    }
                    else {
                        std::string name(argv[i] + 2);
                        if (options.count(name) == 0) {
                            errors.push_back("undefined option: --" + name);
                            continue;
                        }
                        if (options[name]->has_value()) {
                            if (i + 1 >= argc) {
                                errors.push_back("option needs value: --" + name);
                                continue;
                            }
                            else {
                                i++;
                                set_option(name, argv[i]);
                            }
                        }
                        else {
                            set_option(name);
                        }
                    }
                }
                else if (strncmp(argv[i], "-", 1) == 0) {
                    if (!argv[i][1]) continue;
                    char last = argv[i][1];
                    for (int j = 2; argv[i][j]; j++) {
                        last = argv[i][j];
                        if (lookup.count(argv[i][j - 1]) == 0) {
                            errors.push_back(std::string("undefined short option: -") + argv[i][j - 1]);
                            continue;
                        }
                        if (lookup[argv[i][j - 1]] == "") {
                            errors.push_back(std::string("ambiguous short option: -") + argv[i][j - 1]);
                            continue;
                        }
                        set_option(lookup[argv[i][j - 1]]);
                    }

                    if (lookup.count(last) == 0) {
                        errors.push_back(std::string("undefined short option: -") + last);
                        continue;
                    }
                    if (lookup[last] == "") {
                        errors.push_back(std::string("ambiguous short option: -") + last);
                        continue;
                    }

                    if (i + 1<argc && options[lookup[last]]->has_value()) {
                        set_option(lookup[last], argv[i + 1]);
                        i++;
                    }
                    else {
                        set_option(lookup[last]);
                    }
                }
                else {
                    others.push_back(argv[i]);
                }
            }

            for (std::map<std::string, option_base*>::iterator p = options.begin();
                p != options.end(); p++)
                if (!p->second->valid())
                    errors.push_back("need option: --" + std::string(p->first));

            return errors.size() == 0;
        }

        void parse_check(const std::string &arg) {
            if (!options.count("help"))
                add("help", '?', "print this message");
            check(0, parse(arg));
        }

        void parse_check(const std::vector<std::string> &args) {
            if (!options.count("help"))
                add("help", '?', "print this message");
            check(args.size(), parse(args));
        }

        void parse_check(int argc, char *argv[]) {
            if (!options.count("help"))
                add("help", '?', "print this message");
            check(argc, parse(argc, argv));
        }

        std::string error() const {
            return errors.size()>0 ? errors[0] : "";
        }

        std::string error_full() const {
            std::ostringstream oss;
            for (size_t i = 0; i<errors.size(); i++)
                oss << errors[i] << std::endl;
            return oss.str();
        }

        std::string usage() const {
            std::ostringstream oss;
            oss << "usage: " << prog_name << " ";
            for (size_t i = 0; i<ordered.size(); i++) {
                if (ordered[i]->must())
                    oss << ordered[i]->short_description() << " ";
            }

            oss << "[options] ... " << ftr << std::endl;
            oss << "options:" << std::endl;

            size_t max_width = 0;
            for (size_t i = 0; i<ordered.size(); i++) {
                max_width = std::max(max_width, ordered[i]->name().length());
            }
            for (size_t i = 0; i<ordered.size(); i++) {
                if (ordered[i]->short_name()) {
                    oss << "  -" << ordered[i]->short_name() << ", ";
                }
                else {
                    oss << "      ";
                }

                oss << "--" << ordered[i]->name();
                for (size_t j = ordered[i]->name().length(); j<max_width + 4; j++)
                    oss << ' ';
                oss << ordered[i]->description() << std::endl;
            }
            return oss.str();
        }

    private:

        void check(int argc, bool ok) {
            if ((argc == 1 && !ok) || exist("help")) {
                std::cerr << usage();
                exit(0);
            }

            if (!ok) {
                std::cerr << error() << std::endl << usage();
                exit(1);
            }
        }

        void set_option(const std::string &name) {
            if (options.count(name) == 0) {
                errors.push_back("undefined option: --" + name);
                return;
            }
            if (!options[name]->set()) {
                errors.push_back("option needs value: --" + name);
                return;
            }
        }

        void set_option(const std::string &name, const std::string &value) {
            if (options.count(name) == 0) {
                errors.push_back("undefined option: --" + name);
                return;
            }
            if (!options[name]->set(value)) {
                errors.push_back("option value is invalid: --" + name + "=" + value);
                return;
            }
        }

        class option_base {
        public:
            virtual ~option_base() {}

            virtual bool has_value() const = 0;
            virtual bool set() = 0;
            virtual bool set(const std::string &value) = 0;
            virtual bool has_set() const = 0;
            virtual bool valid() const = 0;
            virtual bool must() const = 0;

            virtual const std::string &name() const = 0;
            virtual char short_name() const = 0;
            virtual const std::string &description() const = 0;
            virtual std::string short_description() const = 0;
        };

        class option_without_value : public option_base {
        public:
            option_without_value(const std::string &name,
                char short_name,
                const std::string &desc)
                :nam(name), snam(short_name), desc(desc), has(false) {
            }
            ~option_without_value() {}

            bool has_value() const { return false; }

            bool set() {
                has = true;
                return true;
            }

            bool set(const std::string &) {
                return false;
            }

            bool has_set() const {
                return has;
            }

            bool valid() const {
                return true;
            }

            bool must() const {
                return false;
            }

            const std::string &name() const {
                return nam;
            }

            char short_name() const {
                return snam;
            }

            const std::string &description() const {
                return desc;
            }

            std::string short_description() const {
                return "--" + nam;
            }

        private:
            std::string nam;
            char snam;
            std::string desc;
            bool has;
        };

        template <class T>
        class option_with_value : public option_base {
        public:
            option_with_value(const std::string &name,
                char short_name,
                bool need,
                const T &def,
                const std::string &desc)
                : nam(name), snam(short_name), need(need), has(false)
                , def(def), actual(def) {
                this->desc = full_description(desc);
            }
            ~option_with_value() {}

            const T &get() const {
                return actual;
            }

            bool has_value() const { return true; }

            bool set() {
                return false;
            }

            bool set(const std::string &value) {
                try {
                    actual = read(value);
                    has = true;
                }
                catch (const std::exception &) {
                    return false;
                }
                return true;
            }

            bool has_set() const {
                return has;
            }

            bool valid() const {
                if (need && !has) return false;
                return true;
            }

            bool must() const {
                return need;
            }

            const std::string &name() const {
                return nam;
            }

            char short_name() const {
                return snam;
            }

            const std::string &description() const {
                return desc;
            }

            std::string short_description() const {
                return "--" + nam + "=" + detail::readable_typename<T>();
            }

        protected:
            std::string full_description(const std::string &desc) {
                return
                    desc + " (" + detail::readable_typename<T>() +
                    (need ? "" : " [=" + detail::default_value<T>(def) + "]")
                    + ")";
            }

            virtual T read(const std::string &s) = 0;

            std::string nam;
            char snam;
            bool need;
            std::string desc;

            bool has;
            T def;
            T actual;
        };

        template <class T, class F>
        class option_with_value_with_reader : public option_with_value<T> {
        public:
            option_with_value_with_reader(const std::string &name,
                char short_name,
                bool need,
                const T def,
                const std::string &desc,
                F reader)
                : option_with_value<T>(name, short_name, need, def, desc), reader(reader) {
            }

        private:
            T read(const std::string &s) {
                return reader(s);
            }

            F reader;
        };

        std::map<std::string, option_base*> options;
        std::vector<option_base*> ordered;
        std::string ftr;

        std::string prog_name;
        std::vector<std::string> others;

        std::vector<std::string> errors;
    };

} // cmdline

测试效果

>20171210_命令行进行解析.exe -p 8888 -h baidu.com -t ftp
ftp://baidu.com:8888

>20171210_命令行进行解析.exe -?
usage: 20171210_命令行进行解析.exe --host=string --port=int [options] ...
options:
  -h, --host    host name (string)
  -p, --port    port number (int)
  -t, --type    protocol type (string [=http])
      --gzip    gzip when transfer
  -?, --help    print this message

>20171210_命令行进行解析.exe -p 8888 -h baidu.com -t ftp
ftp://baidu.com:8888

>20171210_命令行进行解析.exe -p 8888 -h baidu.com --gzip
http://baidu.com:8888
gzip

3、参考

【C++】cmdline —— 轻量级的C++命令行解析库
http://www.mamicode.com/info-detail-1923374.html

c++:改造cmdline用于MSVC下的命令行参数解析
http://blog.csdn.net/10km/article/details/50982993

【C++】cmdline——轻量级的C++命令行解析库的更多相关文章

  1. Python命令行解析库argparse

    2.7之后python不再对optparse模块进行扩展,python标准库推荐使用argparse模块对命令行进行解析. 1.example 有一道面试题:编写一个脚本main.py,使用方式如下: ...

  2. Python命令行解析库argparse(转)

    原文:http://www.cnblogs.com/linxiyue/p/3908623.html 2.7之后python不再对optparse模块进行扩展,python标准库推荐使用argparse ...

  3. .NET:命令行解析器介绍

    背景 经常需要开发一下小工具,之前都是自己解析命令行参数,接触过动态语言社区以后,发现命令行解析有特定的模式和框架可以利用,本文介绍一个 .NET 平台的类库. 示例 需求 拷贝文件,如:CopyFi ...

  4. Python命令行解析argparse常用语法使用简介

    查看原文:http://www.sijitao.net/2000.html python中的命令行解析最简单最原始的方法是使用sys.argv来实现,更高级的可以使用argparse这个模块.argp ...

  5. Noah的学习笔记之Python篇:命令行解析

    Noah的学习笔记之Python篇: 1.装饰器 2.函数“可变长参数” 3.命令行解析 注:本文全原创,作者:Noah Zhang  (http://www.cnblogs.com/noahzn/) ...

  6. python命令行解析工具argparse模块【1】

    argpaser是python中很好用的一个命令行解析模块,使用它我们可以很方便的创建用户友好型命令行程序.而且argparse会自动生成帮助信息和错误信息. 一.示例 例如下面的例子,从命令行中获取 ...

  7. python实现命令行解析的argparse的使用

    参考https://docs.python.org/3.6/library/argparse.html argparse模块使编写用户友好的命令行界面变得很容易.程序定义了它需要什么参数,argpar ...

  8. 使用命令行解析php文件

    使用命令行解析php文件,这样可以调用Log4PHP库中的一些demo,因为默认的输出使用命令行作为输出. 建一个bat文件: echo 以下是使用命令行解析php文件 C:\xampp\php\ph ...

  9. 『Argparse』命令行解析

    一.基本用法 Python标准库推荐使用的命令行解析模块argparse 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的optparse.因为argparse是 ...

随机推荐

  1. 3D开机动画

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  2. 冒泡排序的C、C++实现

    一.冒泡排序 冒泡排序就是重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如数字从大到小.首字母从A到Z)错误就把他们交换过来.走访元素的工作是重复地进行直到没有相邻元素需要交换, ...

  3. 在delphi中我用DBGrid选择多条记录,如何一次把选择的多条记录删掉

    procedure TForm1.btnDoSumClick(Sender: TObject);var  i: Integer;begin  if DBGrid1.SelectedRows.Count ...

  4. Vue入门---属性、style和class绑定方法

    一 .用对象的方法绑定class <!DOCTYPE html> <html> <head> <meta charset="UTF-8"& ...

  5. 学习《Unix/Linux编程实践教程》(1):Unix 系统编程概述

    0.目录 1.概念 2.系统资源 3.学习方法 4.从用户的角度来理解 Unix 4.1 登录--运行程序--注销 4.2 目录操作 4.3 文件操作 5.从系统的角度来理解 Unix 5.1 网络桥 ...

  6. 解决 winform 界面对不齐

    最近做了一个winform的程序,本机上界面对得很齐,到一到客户的机器上就惨不忍睹,一番研究后搞定: 1. AutoScaleMode = None 2. BackgroundImageLayout ...

  7. luogu2678 [NOIp2015]跳石头 (二分答案+贪心)

    先二分出一个x,我们要算使最近的跳跃距离>=x的最少移除数量是否<=M就可以了 然后就别dp了...贪心就完事了...我肯定能不移就不移比较好... #include<bits/st ...

  8. emoji表情与unicode编码互转(JS,JAVA,C#)

    1.表情字符转编码 [C#] Encoding.UTF32.GetBytes("

  9. 解题:SDOI 2017 硬币游戏

    题面 板板的生成函数做法太神仙了,我跑了 朴素的做法是建立AC自动机变成图上的随机游走问题 来仔细考虑一下转移,把状态分成非结尾状态和结尾状态.在一个非结尾状态后补一个串是一定能到达目标串的,但是如果 ...

  10. Javascript面向

    一.前言 面向对象:专注于由哪一个对象来解决这个问题,编程特点是出现了一个类,从类中拿到对象,由这个对象去解决具体问题.       对于调用者来说,面向过程需要调用者自己去实现各种函数.而面向对象, ...