C++解析命令行参数(仿C语言args)

Posted crsky

tags:

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

说好不造轮子的,就管不住这手

#include <cstdio>
#include <string>
#include <vector>


bool ParseChar( const std::string& buf, std::size_t& pos, char& ch, bool& escape )
{
    char c;

    if ( pos == buf.length() )
        return false;

    // Get the character to parse
    c = buf.at( pos++ );

    if ( c == \\ )
    {
        // Parse the escape character

        if ( pos != buf.length() )
        {
            // Get the character to escape
            c = buf.at( pos++ );

            if ( c == \\ || c == " )
            {
                ch = c;
                escape = true;
            }
            else
            {
                // Does not support the character, just hold the ‘\\‘ character
                //  We need move the POS back to prepare for the character parsing
                pos--;
                ch = \\;
                escape = false;
            }
        }
        else
        {
            // We can‘t get the character to escape
            //  Just hold the ‘\\‘ character
            ch = c;
            escape = false;
        }
    }
    else
    {
        // Copy the character

        ch = c;
        escape = false;
    }

    return true;
}

bool ParseToken( const std::string& buf, std::size_t& pos, std::string& token )
{
    char c {};
    bool escape {};
    bool quote {};        // True if parsing a string
    bool doing {};        // True if parsing has started

    // Skip blank characters, if any
    while ( pos != buf.length() )
    {
        c = buf.at( pos );

        if ( c !=   && c != \t )
            break;

        pos++;
    }

    // Clean up the token
    token.clear();

    while ( ParseChar( buf, pos, c, escape ) )
    {
        if ( !doing )
        {
            // Parse the first character

            if ( c == " && !escape )
            {
                // Just mark the beginning of the string, don‘t copy it
                quote = true;
            }
            else
            {
                // Copy the first character of the token
                token.push_back( c );
            }

            // ‘\n‘ is a single character token
            if ( c == \n )
                return true;

            // We have parsed any one character, the parsing has started
            doing = true;
        }
        else
        {
            if ( quote )
            {
                // Copying the character of the string here

                if ( c == " && !escape )
                {
                    // Mark the ending of a string
                    return true;
                }
                else
                {
                    // Copy the character of the string
                    token.push_back( c );
                }
            }
            else
            {
                // Copying the character of the token here

                if ( c == " && !escape )
                {
                    // We accidentally encounter a string beginning mark before the token finished
                    //  We need to finish the token and move the POS back to prepare for the string parsing
                    pos--;
                    return true;
                }

                if ( c == \n )
                {
                    // We accidentally encounter a ‘\n‘ before the token finished
                    //  We need to finish the token and move the POS back to prepare for the ‘\n‘ parsing
                    pos--;
                    return true;
                }

                if ( c ==   || c == \t )
                {
                    // Mark the ending of a string
                    return true;
                }
                else
                {
                    // Copy the character of the token
                    token.push_back( c );
                }
            }
        }
    }

    // If no any characters are parsed, we are at the end of the buffer
    //  returns ‘false‘ to finish the parsing

    return doing;
}

int main()
{
    std::string cmdline = R"(   connect
spawn  1
name "Billy Herrington"
flags          0xffff    ""
desc "boy \\next\" door"    )";

    std::size_t pos {};
    std::string token {};

    while ( ParseToken( cmdline, pos, token ) )
    {
        printf_s( "[%s]\n", token == "\n" ? "\\n" : token.c_str() );
    }

    return 0;
}

输出如下

[connect]
[\n]
[spawn]
[1]
[\n]
[name]
[Billy Herrington]
[\n]
[flags]
[0xffff]
[]
[\n]
[desc]
[boy \next" door]

我对换行符做了点特殊处理,如果不需要可以删掉相关的判断代码

 

以上是关于C++解析命令行参数(仿C语言args)的主要内容,如果未能解决你的问题,请参考以下文章

如何在C++中解析命令行参数

14.Go语言标准库flag基本使用

Go语言标准库之flag

C++编程:命令行参数

C++编程:命令行参数

go语言标准库之flag