为什么我的C ++数组打印相同的值?

时间:2014-03-05 03:55:46

标签: c++ linux process operating-system pipe

我正在编写一个代码,它将执行Linux命令管道。基本上在我的代码中,它将解析用户输入命令,然后使用execvp函数运行它。

但是,要做到这一点,我需要知道命令及其参数。我一直试图让解析正常工作,但是,当我做一个测试用例时,来自存储各自程序的两个数组的输出都是相同的。命令/参数存储在名为prgname1prgname2数组中。

例如,如果我使用参数“ps aux | grep [username]”运行我的程序,则prgname1 [0]和prgname2 [0]的输出都是[username]。它们应分别为psgrep

任何人都可以查看我的代码并查看我可能遇到错误的原因吗?

谢谢!

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <iostream>

#define MAX_PARA_NUM 5
#define MAX_COMMAND_LEN 1024

using namespace std;

int main(int argc, char *argv[]) {
char *prgname1[MAX_PARA_NUM], *prgname2[MAX_PARA_NUM];
char command[MAX_COMMAND_LEN];
int pfd[2];
pipe(pfd);
pid_t cid1, cid2;

char *full = argv[1];
char str[MAX_COMMAND_LEN];
int i = 0;
int j = 0;
int k = 0;
int ind = 0;
while (ind < strlen(full)) {
    if (full[ind] == ' ') {
        strncpy(command, str, i);
        cout << command << endl;
        prgname1[j] = command;
        j++;
        i = 0;
        ind++;
    }
    else {
        str[i] = full[ind];
        i++;
        ind++;
    }

    if(full[ind] == '|') {
        i = 0;
        j = 0;
        ind+=2;
        while (ind < strlen(full)) {
            if (full[ind] == ' ') {
                strncpy(command, str, i);
                cout << command << endl;
                prgname2[j] = command;
                j++;
                i = 0;
                ind++;
            }
            else {
                str[i] = full[ind];
                i++;
                ind++;
            }
            if (ind == strlen(full)) {
                strncpy(command, str, i);
                cout << command << endl;
                prgname2[j] = command;
                break;
            }
        }
    }
}

    // test output here not working correctly
cout << prgname1[0] << endl;
cout << prgname2[0] << endl;

// exits if no parameters passed
if (argc != 2) {
    cout << "Usage:" << argv[0] << endl;
    exit(EXIT_FAILURE);
}

// exits if there is a pipe error
if (pipe(pfd) == -1) {
    cerr << "pipe" << endl;
    exit(EXIT_FAILURE);
}
cid1 = fork();  // creates child process 1

// exits if there is a fork error
if (cid1 == -1 || cid2 == -1) {
    cerr << "fork";
    exit(EXIT_FAILURE);
}
// 1st child process executes and writes to the pipe
if (cid1 == 0) {
    char **p = prgname1;
    close(1);   // closes stdout
    dup(pfd[1]);    // connects pipe output to stdout
    close(pfd[0]);  // closes pipe input as it is not needed
    close(pfd[1]);  // closes pipe output as pipe is connected      
    execvp(prgname1[0], p);
    cerr << "execlp 1 failed" << endl;
    cid2 = fork();
}
// 2nd child process reads from the pipe and executes
else if (cid2 == 0) {
    char **p = prgname2;
    close(0);   // closes stdin
    dup(pfd[0]);    // connects pipe input to stdin
    close(pfd[0]);  // closes pipe input as pipe is connected
    close(pfd[1]);  // closes pipe output as it is not needed
    execvp(prgname2[0], p);
    cerr << "execlp 2 failed" << endl;
}
else {
    sleep(1);
    waitpid(cid1, NULL, 0);
    waitpid(cid2, NULL, 0);
    cout << "Program successfully completed" << endl;
    exit(EXIT_SUCCESS);
}
return 0;

}

1 个答案:

答案 0 :(得分:2)

argv[1]为您提供命令行上的第一个参数 - 而不是整个命令行。如果您想要传递给流程的命令行参数的完整列表,则需要将argv[1]argv[2],...,argv[argc - 1]附加到每个参数之间。

此外,当您处理它时,您正在设置prgname1[index]command的指针,因此每次设置给定的字符指针时,它们都指向相同的位置(因此,它们都是相同的价值)。您需要为prgname1中的每个元素分配空间,并将command复制到其中(使用strncpy)。或者,使用std::stringstd::vector可以消除当前的大部分代码。