我有一个c ++程序,在我的程序中的某个时刻,我需要调用一个c程序并传递一些参数。
我在linux env。
工作文件simpsh是同一目录中的已编译c文件。 resul_simpsh_command是一个包含此类型数据的字符串 --creat --trunc --wronly f1到目前为止。
当我检查我在C程序中收到的值时,它会显示
void execute_simpsh(string resulting_simpsh_command)
{
pid_t pid = fork();
if(pid == -1)
perror("Fork failed!");
else if(pid ==0)
{
char* args[256];
string simpsh ="./simpsh";
args [0] = (char*) simpsh.c_str();
string temp_option_holder="";
int nextCommand=1;
for(int i=0;i<resulting_simpsh_command.length();i++)
{
if(resulting_simpsh_command[i] !=' ')
{
temp_option_holder += resulting_simpsh_command[i];
}
else
{
cout<<"saving to argument: "<<temp_option_holder<<endl;
args [nextCommand] = (char*) temp_option_holder.c_str();
temp_option_holder="";
nextCommand +=1;
}
}
cout<<"command numbers "<<nextCommand<<endl;
args [nextCommand + 1] = NULL;
if(execvp(args[0],args) == -1)
cout<<"Failed to open simpsh, maybe you didnt compile?"<<endl;
exit(1);
}
else
{
//not important for now
}
}
答案 0 :(得分:0)
由于您(错误地)使用args
,很多c_str
数组都将成为无效指针。
一旦重新分配字符串的缓冲区,指针就变为无效
一些args
指针也可能指向相同的东西,即使它们有效。
解决此问题的两个选项(在我的头顶):
动态分配:
args[nextCommand] = strdup(temp_option_holder.c_str());
以后需要重新分配。
或者,如果你可以忍受限制参数长度,你可以使用另一个数组并避免内存管理(但是你需要担心溢出):
char arg_strings[256][ARGUMENT_LENGTH] = {0};
char* args[256] = {0};
// ...
assert(temp_option_holder.length() < ARGUMENT_LENGTH);
strncpy(arg_strings[nextCommand], temp_option_holder.c_str(), ARGUMENT_LENGTH);
args[nextCommand] = arg_strings[nextCommand];
答案 1 :(得分:0)
C ++除std::cout
之外还有很多好东西。使用它们!
此解决方案的核心是{{1}使命令行中的空格为零字节,然后在命令行中指向每个(C)字符串的开头(方便地使用{中的零字节) {1}}作为终结符),将这些指针推送到矢量中,然后我们将传递给std::replace()
。
replace()
请注意,此解决方案将无情地删除命令行中的任何空格,包括引号中的空格,并且不处理换行符,制表符等 - 然后再次,你原来的解决方案也没有不同的行为,所以我会把功能扩展给你。