【发布时间】:2019-09-17 20:48:49
【问题描述】:
我正在使用boost::tokenizer 在 C++ 中标记一个字符串,然后我想将它传递给execv。
考虑以下代码 sn-p(可编译):
#include <iostream>
#include <cstdlib>
#include <vector>
#include <boost/tokenizer.hpp>
// I will put every token into this vector
std::vector<const char*> argc;
// this is the command I want to parse
std::string command = "/bin/ls -la -R";
void test_tokenizer() {
// tokenizer is needed because arguments can be in quotes
boost::tokenizer<boost::escaped_list_separator<char> > scriptArguments(
command,
boost::escaped_list_separator<char>("\\", " ", "\""));
boost::tokenizer<boost::escaped_list_separator<char> >::iterator argument;
for(argument = scriptArguments.begin();
argument!=scriptArguments.end();
++argument) {
argc.push_back(argument->c_str());
std::cout << argument->c_str() << std::endl;
}
argc.push_back(NULL);
}
void test_raw() {
argc.push_back("/bin/ls");
argc.push_back("-l");
argc.push_back("-R");
argc.push_back(NULL);
}
int main() {
// this works OK
/*test_raw();
execv(argc[0], (char* const*)&argc[0]);
std::cerr << "execv failed";
_exit(1);
*/
// this is not working
test_tokenizer();
execv(argc[0], (char* const*)&argc[0]);
std::cerr << "execv failed";
_exit(2);
}
当我运行这个调用test_tokenizer()的脚本时,它会打印'execv failed'。 (虽然它很好地打印了参数)。
但是,如果我将 test_tokenizer 更改为 test_raw 它运行良好。
这一定是一些简单的解决方案,但我没有找到它。
PS.:我还把它放到了一个支持 boost 的在线编译器here。
【问题讨论】:
-
吹毛求疵:
argc的使用令人困惑,因为它通常用于main()的第二个参数。_exit()的使用是不可移植的;更喜欢(标准和功能相同的)exit()。使用execv()应该是#include <unistd.h>。(char* const*)&argc[0]的构造在很多层面上都是错误的(至少是有问题的),无法在一条评论中解释。是的,在 C++ 程序中避免使用 C 字符串 (char *),它们只会让你头疼。 ;-)
标签: c++ boost boost-tokenizer