2017-02-13 117 views
1

我必须写一个程序,将使用execvp当用户输入某个命令启动一个名为demo.cpp新的程序。用户将在格式输入输入execvp无法运行新程序

BG演示字INT1 INT2(忽略字BG的词相关性,我把它存储在一个字符串名为命令在我的代码)。

这是代码:

int main(){ 

char *argv[5]; 
argv[0] = new char[10]; 
argv[1] = new char[10]; 
argv[2] = new char[10]; 
argv[3] = new char[10]; 
argv[4] = nullptr; 


string command; 
pid_t PID; 

cin>>command; //store the string 'bg' 

cin>>argv[0]>>argv[1]>>argv[2]>>argv[3]; 

PID = fork(); 

if(PID<0){ 
    perror("Fork failed!"); 
} 

else if(PID==0){ 

    if(execvp("./demo.cpp",argv)<0) 
      printf("Failed"); 
    } 

wait(0); 

return 0; 
} 

每次代码打印 “失败”。我唯一能想到的是,也许在传递给execvp的参数格式上有错误。此代码和demo.cpp存储在同一个文件夹中。

+2

什么是' 。/ demo.cpp'?它是一个C++源文件吗?你不能执行一个C++源文件。 – mch

+0

搜索上如此相似的问题,检查这个问题,例如 http://stackoverflow.com/questions/14301407/how-does-execvp-run-a-command – Laza

+0

@mch:我是愚蠢的!当然,你不能执行C++源文件。 –

回答

2

你有两个问题:一是execvp需要提供的参数列表为空值终止。您需要

char *argv[5]; // Not 4. 

    ... // input as before 

    argv[4] = nullptr; 

顺便说一句,我个人将其更改为:

std::array<std::string,4> arguments; 
    std::cin>>arguments[0]>>arguments[1]>>arguments[2]>>arguments[3]; 
    char *argv[5]; 
    for (size_t i = 0; i<4; i++) { 
     argv[i] = const_cast<char*>(arguments[i].c_str()); 
    } 
    argv[4] = nullptr; 

关键是要做到投入std::string,然后拿到字符指针之后。这样可以避免任何缓冲区溢出的风险。 (另一方面,const_cast不是很好 - 但我很确定它实际上是安全的。)

其次,您不能通过exec* C++源文件的名称!你必须生成可执行文件(可能调用它demo),然后exec的是:(你还需要确保当前目录是包含可执行文件的目录)

if(execvp("./demo",argv)<0) 

+0

我尝试了第一个建议,但仍然失败,尽管我已经编辑了问题中的代码以合并您的建议 – Sim

+0

您是对的,错误是我传递了源文件!为什么没有教程提到这个细节! – Sim