命令行解析函数,用于将 GetCommandLine()
返回的字符串解析为若干个参数,以便传递给
getopt
等需要 argc
、argv
形式参数的函数使用。
#include <vector>
#include <string>
std::vector<std::string> parse_command_line(const char *cmdline)
{
std::vector<std::string> result;
std::string token;
int state = 0;
while (*cmdline)
{
switch (state)
{
case 0:
switch (*cmdline)
{
case ' ':
if (token.size())
{
result.push_back(token);
token.clear();
}
break;
case '\"':
state = 1;
break;
case '\\':
state = 6;
break;
default:
token += *cmdline;
}
break;
case 1:
switch (*cmdline)
{
case '\"':
state = 3;
break;
case '\\':
state = 7;
break;
default:
token += *cmdline;
state = 2;
}
break;
case 2:
switch (*cmdline)
{
case '\"':
state = 4;
break;
case '\\':
state = 7;
break;
default:
token += *cmdline;
}
break;
case 3:
switch (*cmdline)
{
case ' ':
result.push_back(token);
token.clear();
state = 0;
break;
case '\\':
state = 6;
break;
case '\"':
default:
token += *cmdline;
state = 0;
}
break;
case 4:
switch (*cmdline)
{
case '\"':
state = 5;
break;
case ' ':
result.push_back(token);
token.clear();
state = 0;
break;
case '\\':
state = 6;
break;
default:
token += *cmdline;
state = 0;
break;
}
break;
case 5:
switch (*cmdline)
{
case '\\':
state = 7;
break;
default:
token += *cmdline;
state = 2;
}
break;
case 6:
switch (*cmdline)
{
case ' ':
token += '\\';
result.push_back(token);
token.clear();
break;
case '\"':
token += *cmdline;
break;
default:
token += '\\';
token += *cmdline;
}
state = 0;
break;
case 7:
switch (*cmdline)
{
case '\"':
token += *cmdline;
break;
default:
token += '\\';
token += *cmdline;
}
state = 2;
}
++cmdline;
}
if (token.size())
result.push_back(token);
return result;
}
使用方法如下:
int argc;
char **argv;
std::vector<std::string> args = parse_command_line(GetCommandLine());
argv = new char *[(argc = args.size()) + 1];
int i;
for (i = 0; i < argc; ++i)
argv[i] = (char *) args[i].c_str();
argv[i] = NULL;