【问题标题】:Why is my C++ array printing the same values?为什么我的 C++ 数组打印相同的值?
【发布时间】:2014-04-06 22:42:42
【问题描述】:

我正在编写用于执行 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;

}

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多