1. 程式人生 > >C++解析命令行參數(仿C語言args)

C++解析命令行參數(仿C語言args)

bre args returns sed lse sta turn 刪掉 sin

說好不造輪子的,就管不住這手

#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)