说好不造轮子的,就管不住这手
#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]
我对换行符做了点特殊处理,如果不需要可以删掉相关的判断代码
来源:https://www.cnblogs.com/crsky/p/10779692.html