C++ 标准风格 Stringlist 参数解析器 支持多种参数解析(更新中)

意义何在

这个东西有什么用呢 就是你在进行Win32API编程的时候,你写的 WinMain (wWinMain)函数它传入的可不是 argc 和 argv ,是一整个的 LPSTR lpCmdLine (或者LPWSTR)。

那么,怎么优雅地解析这个 lpCmdLine 呢?(支持 Unicode)

下面给出一种解决方案。

注:该库仍不完善,示例也没有覆盖到所有的可能情况,它甚至连启用 CaseInsensitive 都不支持。但是这是一个 “活跃” 的项目,所以会尽快完善。

主体介绍

主要思路:定义一个优雅的 StringList 类,通过 std::stringstream 进行参数的分割,然后就可以优雅的用 string::find 一样的代码进行参数解析了 :P

更新

V1 (2023-05-04) 仅 StringList 库部分代码 实现基础解析

V2 自己在改Bug和兼容性 没有上传

ParamParser 参数解析器

代码部分

stringlist.h

#pragma once

#include <string>
#include <sstream>
#include <vector>

namespace std {

    template <typename _tcType>
    class _tagStringList {
        using _tagString = std::basic_string<_tcType, std::char_traits<_tcType>, std::allocator<_tcType>>;
        using _tagStringStream = std::basic_stringstream<_tcType, std::char_traits<_tcType>, std::allocator<_tcType>>;
    private:

    public:
        static const size_t npos = -1;
        struct size_t_d {
            size_t a, b;
            size_t_d(){};
            size_t_d(size_t _a,size_t _b):a(_a),b(_b){}
        };

        std::vector<_tagString> list;

        _tagStringList(_tagString __Source) {
            if (!__Source.empty()) {
                _tagStringStream slstr; _tagString tmpstr;
                slstr << __Source;
                while (slstr >> tmpstr) {
                    list.push_back(tmpstr);
                }
            }
        }

        size_t findItem(string _item, size_t beginItem = 0) {
            for(size_t i = 0; i < list.size(); i++) {
                if(list[i]==_item) return i;
            }
            return npos;
        }

        size_t_d findItemContent(string _itemc, size_t beginItem = 0, size_t beginContent = 0) {
            size_t lsp;
            for(size_t i = 0; i < list.size(); i++) {
                if((lsp = list[i].find(_itemc, beginContent)) != _tagString::npos) return size_t_d(i, lsp);
            }
            return size_t_d(npos, npos);
        }

        inline size_t size() { return list.size(); }

        inline _tagString operator [] (size_t pos) { return list[pos]; }
        inline _tagString at(size_t pos) { return list.at(pos); }

        using iterator = typename::std::vector<_tagString>::iterator;

        inline iterator begin() { return list.begin(); }
        inline iterator end() { return list.end(); }
    };

    using StringList = _tagStringList<char>;
    using wStringList = _tagStringList<wchar_t>;

} //namespace std

//local clear
#undef _tagString
#undef _tagStringStream

paramparser.h

// 还没完全实现 先不放了

使用示例

#include <windows.h>
#include <string>
#include <stdio.h>

#include "stringlist.h"

using namespace std;

#define USER_DEFINED_HELP_DOCUMENT "[HELP NOT INCLUDED]"

int ReadConfig(string Filename = "") {

    ///TODO: Read your config here.

    /*
    FILE *pf;
    if (Filename.empty()) fopen_s(&pf, "scuconfig", "rb");
        else fopen_s(&pf, Filename.c_str(), "rb");
    if (pf == NULL) return false; //Doesn't have a config file.
    //fread_s(&UserSettings, sizeof(UserSettings), sizeof(UserSettings), 1, pf);
    fread(&UserSettings, sizeof(UserSettings), 1, pf);
    return true;*/
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    string strCmdLine(lpCmdLine); //convert LPSTR to string.
    if (strCmdLine.empty()) { //if no parameters got...

        ///TODO: do anything you want!!!

    } else { //Ohh, user wants to do something.
        StringList arglist(strCmdLine);
        size_t posbuf;

        //If user is asking for help ducument
        if (arglist.findItem("-h")!=StringList::npos) {
            printf("%s", USER_DEFINED_HELP_DOCUMENT);
            return 0;
        }

        //If user specify config file.
        if ((posbuf=arglist.findItem("-c"))!=StringList::npos) ReadConfig(arglist[posbuf]);
            else ReadConfig(); //read default config.
        
        //If user enables debug mode.
        //This parameter can use with no suffix, or with one suffix.
        if ((posbuf=arglist.findItem("-debug"))!=StringList::npos) {
            //UserSettings.debug = true;
            printf("Debug mode enabled: ");
            if (arglist.size()>posbuf+1) {
                int debugLevel_temp;
                debugLevel_temp = atoi(arglist.at(posbuf+1).c_str());
                if(debugLevel_temp&&debugLevel_temp<=4) ; //UserSettings.debugLevel = debugLevel_temp;
                printf("level %d", debugLevel_temp);
            }
            printf("\n");
        }

        //With a string
        if ((posbuf=arglist.findItem("-w"))!=StringList::npos) {
            if (arglist.size()>posbuf+1) {
                ///TODO: just storage arglist.at(posbuf+1);
                string mystring = arglist.at(posbuf+1);
            }
        }

        //Default parameter
        if ((posbuf=arglist.findItem("-os"))!=StringList::npos) {
            string mystring;
            if (arglist.size()>posbuf+1) {
                mystring = arglist.at(posbuf+1);
            } else mystring = string("Default value!");
        }

        //With a number
        if ((posbuf=arglist.findItem("-es"))!=StringList::npos) {
            if (arglist.size()>posbuf+1) {
                int tmp; tmp = atoi(arglist.at(posbuf+1).c_str());
                ///TODO: Check if atoi runs into errors, then Storage tmp!
            } else { //If it is a must
                printf("argument \"-es\" must be followed by an integer!\n");
                return 1;
            }
        }
    }

    //anything else?

    return 0;
}

使用 tdm-gcc 10.3.0 如下命令可以正常编译:

gcc -o test.exe test.cpp -std=c++11 -lstdc++

运行结果

运行结果 - 图片无法显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用boost::sprirt编写的表达式解析器,代码很容易扩展,功能很强大,适合做功能强大的客户化定义程序。 -----------表达式解析--------- 已定义的函数有:PI,SIN,COS,TAN,,ABS,EXP,LOGN,POW,SQRT,FORMAT,LENGTH,SUBSTR 强制类型转换请使用:(数据类型)数据 例如:(int) "100" 的值为int型100 已定义的变量有:var1=123,var2=this is a string 请输入您的表达式>>1+2 计算结果:3 XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- 1+2 --> <parsetree version="1.0"> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="integer_const"> <value>1</value> </parsenode> <parsenode rule="integer_const"> <value>2</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:integer 计算结果:3 请输入您的表达式>>"ab"+"cd" 计算结果:"abcd" XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- "ab"+"cd" --> <parsetree version="1.0"> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="string_const"> <value>"ab"</value> </parsenode> <parsenode rule="string_const"> <value>"cd"</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:string 计算结果:abcd 请输入您的表达式>>format("1+2=%d",1+2) 计算结果:format("1+2=%d",3) XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- format("1+2=%d",1+2) --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>format</value> <parsenode rule="exprlist"> <parsenode rule="string_const"> <value>"1+2=%d"</value> </parsenode> <parsenode rule="add_expr"> <value>+</value> <parsenode rule="integer_const"> <value>1</value> </parsenode> <parsenode rule="integer_const"> <value>2</value> </parsenode> </parsenode> </parsenode> </parsenode> </parsetree> 计算结果数据类型:string 计算结果:1+2=3 请输入您的表达式>>PI() 计算结果:PI() XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- PI() --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>PI</value> </parsenode> </parsetree> 计算结果数据类型:double 计算结果:3.1415926535897931 请输入您的表达式>>cos(1.5) 计算结果:cos(1.5) XML格式显示计算过程: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE parsetree SYSTEM "parsetree.dtd"> <!-- cos(1.5) --> <parsetree version="1.0"> <parsenode rule="function_identifier"> <value>cos</value> <parsenode rule="double_const"> <value>1.5</value> </parsenode> </parsenode> </parsetree> 计算结果数据类型:double 计算结果:0.070737201667702906 请输入您的表达式>>q

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值