C ++使用execvp和字符串数组

时间:2015-02-25 06:24:41

标签: c++ arrays string

我正在编写一个程序,用任何数量的参数执行Unix命令。我使用常规字符串时接收输入和制作令牌没有问题。但是,execvp只接受一个指针数组,我不知道如何将字符串数组转换为此。这就是我所拥有的:

#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
int main()
{
while (true)
{
    int argc = 0;
    std::istringstream iss;
    std::string command;
    std::cout << "$> ";
    getline(std::cin, command);
    iss.str(command);
    for (unsigned i = 0; i <= command.length(); i++)
    {
        if (command[i] == ' ' || command[i] == '\0')
        {
            argc++;
        }
    }
    std::string arr[argc+1];
    for (int i = 0; i < argc; i++)
    {
        iss >> arr[i];
    }
    if (arr[0].compare("quit"))
    {
        break;
    }
    else
    {
        char*argv[argc+1];
        for (int i = 0; i < argc; i++)
        {
            argv[i] = arr[i].c_str(); //This line is wrong
        }
        argv[argc] = NULL;
        execvp(argv[0], argv);
    }
}
return 0;
}

我尝试了各种方法,无法弄清楚如何以正确的方式将字符串转换为字符数组。像strcpy这样的方法不起作用,因为每个参数的长度会有所不同。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

你有很小的错误。

替换:

  1. argv[i] = arr[i].c_str();argv[i] = const_cast<char*>(arr[i].c_str());
  2. if(arr[0].compare("quit"))if(!arr[0].compare("quit"))
  3. 你很高兴,这适用于任何编译器 运行here

    但是我有一些建议使用fork,所以它不会一次只运行一个命令。

    示例here

答案 1 :(得分:1)

您的问题是您的阵列持有char*,而std::string::c_str()则返回const char*。它不能存储在你的数组中,因为它会失去常量。

如果您正在使用符合C ++ 11的编译器,则可以使用&arr[i][0]获取指向内部字符串缓冲区的非const指针。

如果您没有使用符合C ++ 11的编译器,则内部缓冲区可能不会以空值终止,因此您唯一的选择是使用newmalloc正确分配大小缓冲区,然后将strcpy字符串放入其中。

char* buffer = new char[arr[i].length() + 1];
strcpy(buffer, arr[i].c_str());
argv[i] = buffer;

答案 2 :(得分:0)

您可以通过以下方式确保数组中每个字符串末尾的null终结符:

for (int i = 0; i < argc; i++)
{
    iss >> arr[i];
    arr[i].push_back('\0');
}

然后你可以简单地捕获指向每个字符串的第一个字符的指针。干净安全,没有任何const_cast

for (int i = 0; i < argc; i++)
{
    argv[i] = &arr[i][0];
}