C++ 将令牌强制转换为char*const时,使用boost标记化字符串失败*
我使用C++ 将令牌强制转换为char*const时,使用boost标记化字符串失败*,c++,boost,boost-tokenizer,C++,Boost,Boost Tokenizer,我使用 >在C++中标记字符串,然后将其传递给 ExcV< /Cord> 考虑以下代码段(可编译): #包括 #包括 #包括 #包括 //我将把每个标记都放入这个向量中 std::载体argc; //这是我要分析的命令 std::string命令=“/bin/ls-la-R”; 无效测试\标记器(){ //需要标记器,因为参数可以在引号中 boost::标记器脚本参数( 指挥部, boost::转义\u列表\u分隔符(“\\”,“,”); boost::tokenizer::迭代器参数; for
#包括
#包括
#包括
#包括
//我将把每个标记都放入这个向量中
std::载体argc;
//这是我要分析的命令
std::string命令=“/bin/ls-la-R”;
无效测试\标记器(){
//需要标记器,因为参数可以在引号中
boost::标记器脚本参数(
指挥部,
boost::转义\u列表\u分隔符(“\\”,“,”);
boost::tokenizer::迭代器参数;
for(argument=scriptArguments.begin();
参数!=scriptArguments.end();
++(论据){
argc.push_back(参数->c_str());
std::cout c_str()
因此,当迭代器被修改时,参数->c_str()
指向的字符数组可能会被修改或失效,其生存期最晚将以参数的生存期结束
因此,当您尝试使用argc
时,程序具有未定义的行为
如果您想继续使用boost::tokenizer
,我建议将令牌保存在std::vector
中,然后将它们转换为指针数组。挑剔之处:argc
的用法令人困惑,因为它通常用于main()
的第二个参数。\u exit()
是不可移植的;更喜欢(标准且功能相同的)exit()
。execv()
的使用应该#包括
。构造(char*const*)&argc[0]
在很多层次上都是错误的(至少有问题),无法在一个注释中解释。是的,避免使用C字符串(char*
)在C++程序中,它们只会给你带来麻烦。-谢谢。如果有更合适的东西,我会高兴地放弃记录器。无论如何,把它们存储在向量中是很好的,但之后我必须为ReXV构建一个“conchchar *”数组。这里是相关的StAdExtOpLoad主题:所以我更喜欢“最近”或“现代”。丹IL:这里的问题是C++中“适当”和“方便”的转换,以及“代码> Excel())/>代码(“不是C,C++”)的“适当”。什么是前进的最佳方法取决于真正的用例…@ DeSun:是的,你完全正确。假设我有一个字符串变量命令。我想要执行这个命令。它可能包含参数,甚至在引号中。语言是C++,OS Linux。如果丹尼尔基本上是你想执行的任意shell命令,您可以简单地execl
一个带有-c
选项的shell,并将整个命令作为单个参数传递。这样您就可以将问题委托给shell。(如果您不想在shell中创建子进程,请将exec
前缀添加到命令中。)如果命令
来自不受信任的源,不应执行任意代码,请不要这样做。
#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);
}