说好不造轮子的,就管不住这手
#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 != ' ' ) 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 ); } // ' ' is a single character token if ( c == ' ' ) 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 == ' ' ) { // We accidentally encounter a ' ' before the token finished // We need to finish the token and move the POS back to prepare for the ' ' parsing pos--; return true; } if ( c == ' ' || c == ' ' ) { // 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] ", token == " " ? "\n" : token.c_str() ); } return 0; }
输出如下
[connect] [ ] [spawn] [1] [ ] [name] [Billy Herrington] [ ] [flags] [0xffff] [] [ ] [desc] [boy ext" door]
我对换行符做了点特殊处理,如果不需要可以删掉相关的判断代码