我要写一个带有2个命令及其参数(最多5个)的赋值,它会将一个输出管道输出到另一个。然后循环,再次请求两个命令,直到退出为止。
我遇到的问题是在第二个循环中输入值后,会发生奇怪的事情,比如在输入第二个命令后输出“Enter Command 1”(两者都出现在同一行)。我还注意到输入ls -l然后cat工作,例如,但输入ls -l然后wc会导致问题。有人会介意看看并可能帮助我吗?我整天都在工作,我还有一个多小时的时间来完成它。
侧注:是的,我意识到执行命令设置有点愚蠢,但我没时间,没有时间摆弄它。它有效。
#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sstream>
using namespace std;
int main(){
//Our imput strings that the user enters.
string input1;
string input2;
//Temporary string.
string s;
//Array to hold the items passed in.
string arg1[6];
string arg2[6];
//A count of how many items they passed in.
int carg1;
int carg2;
//Loop until quit.
while(true){
//Set all our values to empty/zero
carg1 = 0;
carg2 = 0;
input1.clear();
input2.clear();
//Prompt for first command.
while(input1.empty()){
cout << "Command One (or quit): ";
getline(cin, input1);
}
//Split the string by the space to get the pieces of the command.
istringstream iss1(input1);
while (getline(iss1, s, ' ')) {
arg1[carg1] = s;
carg1++;
}
//Check if command is quit and exit if true.
if(arg1[0].compare("quit") == 0){
return 0;
}
//Prompt for command 2.
while(input2.empty()){
cout << "Command Two: ";
cin >> input2;
}
//Once again, split based on spaces.
istringstream iss2(input2);
while (getline(iss2, s, ' ')) {
//arg2.push_front(s);
arg2[carg2] = s;
carg2++;
}
//Initialize the pipe.
int pipefd[2];
if(pipe(pipefd) == -1){
perror("Pipe");
exit(EXIT_FAILURE);
}
//Create the fork to two processes.
int pid = fork();
//Switch to check for parent and child.
switch(pid){
case 0: //Child process
//Close the read pipe and standard input.
close(pipefd[0]);
close(1);
//Copy data
dup(pipefd[1]);
//Close other end of the pipe
close(pipefd[1]);
//Execute the first command. Based on how many params, call different ones.
switch(carg1){
case 1:
execlp(arg1[0].c_str(), arg1[0].c_str(), (char*)NULL);
break;
case 2:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), (char*)NULL);
break;
case 3:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), (char*)NULL);
break;
case 4:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), (char*)NULL);
break;
case 5:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), (char*)NULL);
break;
case 6:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), arg1[5].c_str(), (char*)NULL);
break;
case 7:
execlp(arg1[0].c_str(), arg1[0].c_str(), arg1[1].c_str(), arg1[2].c_str(), arg1[3].c_str(), arg1[4].c_str(), arg1[5].c_str(), arg1[6].c_str(), (char*)NULL);
break;
}
return 0;
case -1: //Error
perror("fork");
exit(EXIT_FAILURE);
default: //Parent Process
//Wait for initial command to execute.
wait(&pid);
//Fork into two processes.
int pid2 = fork();
//Switch based on child and parent.
switch(pid2){
case 0: //Child process
//Close write end of pipe and standard output.
close(pipefd[1]);
close(0);
//Duplicate to standard input
dup(pipefd[0]);
//Close read end.
close(pipefd[0]);
//Execute proper command based on params
switch(carg2){
case 1:
execlp(arg2[0].c_str(), arg2[0].c_str(), (char*)NULL);
break;
case 2:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), (char*)NULL);
break;
case 3:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), (char*)NULL);
break;
case 4:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), (char*)NULL);
break;
case 5:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), (char*)NULL);
break;
case 6:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), arg2[5].c_str(), (char*)NULL);
break;
case 7:
execlp(arg2[0].c_str(), arg2[0].c_str(), arg2[1].c_str(), arg2[2].c_str(), arg2[3].c_str(), arg2[4].c_str(), arg2[5].c_str(), arg2[6].c_str(), (char*)NULL);
break;
}
return 0;
case -1: //Error
perror("fork");
exit(EXIT_FAILURE);
default: //Parent Process
//wait(&pid2);
break;
}
}
}
}
示例输出:
nick@nick-VirtualBox ~/Documents/Assign10 $ ./z1615629
Command One (or quit): ls -l
Command Two: wc
Command One (or quit): Command One (or quit): quit
示例输出:
nick@nick-VirtualBox ~/Documents/Assign10 $ ./z1615629
Command One (or quit): ls -l
Command Two: cat
Command One (or quit): Command One (or quit):
total 32
-rwxr-xr-x 1 nick nick 13358 Nov 20 15:46 z1615629
-rw-r--r-- 1 nick nick 4544 Nov 20 15:46 z1615629.cxx
-rw-r--r-- 1 nick nick 8104 Nov 20 15:46 z1615629.o
答案 0 :(得分:1)
因为您不使用函数,所以在命令提示和读取循环中存在不对称行为:
//Prompt for first command.
while (input1.empty()){
cout << "Command One (or quit): ";
getline(cin, input1);
}
...
//Prompt for command 2.
while (input2.empty()){
cout << "Command Two: ";
cin >> input2;
}
第二个命令只包含一个单词。新线被遗忘,在下一个周期给你双重提示。在第二个提示循环中使用getline(cin, input2)
。如果你使用函数,你就会获得一致性 - 函数可以让生活更轻松,而不是更难。
您需要关闭父进程中的管道。您还需要wait()
at:
default: //Parent Process
//wait(&pid2);
break;
使用:
default: // Parent process
close(pipefd[0]);
close(pipefd[1]);
while (wait(0) != -1)
;
break;
答案 1 :(得分:1)
我知道它没有解决这个问题,但这里是原始代码C ++ - ified。
我已经注意保持C ++ 03兼容。我只假设绑定的TR1(尽管mem_fun_ref的咒语应该很容易写)。
请注意缩小尺寸:删除88 LoC(&gt; 50%)
#include <iostream>
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <tr1/functional>
using namespace std;
void execute(std::vector<string> const& arg1) {
vector<char const*> argv(arg1.size());
transform(arg1.begin(), arg1.end(), argv.begin(), tr1::bind(&std::string::c_str, tr1::placeholders::_1));
argv.push_back(NULL);
execvp(argv[0], (char* const*) &argv[0]); // TODO FIXME error handling?
exit(EXIT_FAILURE);
}
std::vector<string> getinput(std::string prompt) {
vector<string> result;
string input;
//Prompt for first command.
while(input.empty()) {
cout << prompt;
getline(cin, input);
}
//Split the string by the space to get the pieces of the command.
{
istringstream iss(input);
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(result));
}
return result;
}
int main() {
//Loop until quit.
while(true) {
const std::vector<string> cmd1 = getinput("Command One (or quit): ");
if(cmd1.empty() || cmd1[0] == "quit") {
return 0;
}
const std::vector<string> cmd2 = getinput("Command Two: ");
//Initialize the pipe.
int pipefd[2];
if(pipe(pipefd) == -1) {
perror("Pipe");
exit(EXIT_FAILURE);
}
int pid = fork(); //Create the fork to two processes.
switch(pid) { // Switch to check for parent and child.
case 0: // Child process
close(pipefd[0]); // Close the read pipe and standard input.
close(1);
dup(pipefd[1]); // Copy data
close(pipefd[1]); // Close other end of the pipe
execute(cmd1);
return 0;
case -1: // Error
perror("fork");
exit(EXIT_FAILURE);
default: // Parent Process
wait(&pid); // Wait for initial command to execute.
int pid2 = fork(); // Fork into two processes.
switch(pid2) { // Switch based on child and parent.
case 0: // Child process
close(pipefd[1]); // Close write end of pipe and standard output.
close(0);
dup(pipefd[0]); // Duplicate to standard input
close(pipefd[0]); // Close read end.
execute(cmd2); // Execute proper command based on params
return 0;
case -1: // Error
perror("fork");
exit(EXIT_FAILURE);
default: // Parent Process
//wait(&pid2);
break;
}
}
}
}
免责声明它编译,我没有运行它(我不知道输入它的输入,以及如何,无论如何。)