#include #include#include
bool ParseChar( const std::string& buf, std::size_t& pos, char& ch, bool&escape )
{charc;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 )
{charc {};boolescape {};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
returndoing;
}intmain()
{
std::string cmdline = R"( connect
spawn 1name"Billy Herrington"flags0xffff ""desc"boy \\next\" door" )";
std::size_t pos {};
std::stringtoken {};while( ParseToken( cmdline, pos, token ) )
{
printf_s("[%s]\n", token == "\n" ? "\\n": token.c_str() );
}return 0;
}