我需要将命令行字符串解析为argv格式,以便将其传递给execvpe。基本上一个Linux与Windows的CommandLineToArgvW()等效。我可以打电话来做这个功能或库吗?或者我是否必须编写自己的解析器? (我希望如果我需要这样做,我可以从BASH偷走,因为我的程序是GPL ......)
实施例: 我有三个变量:
const char* file = "someapplication";
const char* parameters = "param1 -option1 param2";
const char* environment[] = { "Something=something", NULL };
我希望将它传递给execvpe:
execvpe(file, /* parsed parameters */, environment);
PS:我不想要文件名扩展,但我想引用和转义
答案 0 :(得分:3)
我在评论(http://bbgen.net/blog/2011/06/string-to-argc-argv)中使用了rve给出的链接,这解决了我的问题。提出他的评论,而不是我的回答!
答案 1 :(得分:1)
使用我的nargv
程序。我真的用这个答案将这个问题打败了:https://stackoverflow.com/a/10071763/735796 nargv
意味着新的参数向量。它支持shell将字符串解析为单独元素的所有内容。例如,它支持双引号,单引号和字符串连接。
答案 2 :(得分:0)
char *strtok(char *s, const char *delim)
正是您要找的
char *s
将是标准输入,char *delim
将是' '
答案 3 :(得分:0)
也许我错过了一些东西,但为什么不把&argv[1]
作为参数和使用getenv()
获得的环境作为环境传递?
修改强> 如果需要不同的分隔符,可以使用环境变量IFS(内部字段分隔符)来实现此目的。
答案 4 :(得分:0)
以下是我第一次尝试复制Windows shell库中CommandLineToArgvW()
函数的功能。它仅使用标准函数和类型,不使用Boost。除了对strdup()
的一次调用外,它与平台无关,适用于Windows和Linux环境。它处理单引号或双引号的参数。
// Snippet copied from a larger file. I hope I added all the necessary includes.
#include <string>
#include <string.h>
#include <vector>
using namespace std;
char ** CommandLineToArgv( string const & line, int & argc )
{
typedef vector<char *> CharPtrVector;
char const * WHITESPACE_STR = " \n\r\t";
char const SPACE = ' ';
char const TAB = '\t';
char const DQUOTE = '\"';
char const SQUOTE = '\'';
char const TERM = '\0';
//--------------------------------------------------------------------------
// Copy the command line string to a character array.
// strdup() uses malloc() to get memory for the new string.
#if defined( WIN32 )
char * pLine = _strdup( line.c_str() );
#else
char * pLine = strdup( line.c_str() );
#endif
//--------------------------------------------------------------------------
// Crawl the character array and tokenize in place.
CharPtrVector tokens;
char * pCursor = pLine;
while ( *pCursor )
{
// Whitespace.
if ( *pCursor == SPACE || *pCursor == TAB )
{
++pCursor;
}
// Double quoted token.
else if ( *pCursor == DQUOTE )
{
// Begin of token is one char past the begin quote.
// Replace the quote with whitespace.
tokens.push_back( pCursor + 1 );
*pCursor = SPACE;
char * pEnd = strchr( pCursor + 1, DQUOTE );
if ( pEnd )
{
// End of token is one char before the end quote.
// Replace the quote with terminator, and advance cursor.
*pEnd = TERM;
pCursor = pEnd + 1;
}
else
{
// End of token is end of line.
break;
}
}
// Single quoted token.
else if ( *pCursor == SQUOTE )
{
// Begin of token is one char past the begin quote.
// Replace the quote with whitespace.
tokens.push_back( pCursor + 1 );
*pCursor = SPACE;
char * pEnd = strchr( pCursor + 1, SQUOTE );
if ( pEnd )
{
// End of token is one char before the end quote.
// Replace the quote with terminator, and advance cursor.
*pEnd = TERM;
pCursor = pEnd + 1;
}
else
{
// End of token is end of line.
break;
}
}
// Unquoted token.
else
{
// Begin of token is at cursor.
tokens.push_back( pCursor );
char * pEnd = strpbrk( pCursor + 1, WHITESPACE_STR );
if ( pEnd )
{
// End of token is one char before the next whitespace.
// Replace whitespace with terminator, and advance cursor.
*pEnd = TERM;
pCursor = pEnd + 1;
}
else
{
// End of token is end of line.
break;
}
}
}
//--------------------------------------------------------------------------
// Fill the argv array.
argc = tokens.size();
char ** argv = static_cast<char **>( malloc( argc * sizeof( char * ) ) );
int a = 0;
for ( CharPtrVector::const_iterator it = tokens.begin(); it != tokens.end(); ++it )
{
argv[ a++ ] = (*it);
}
return argv;
}