0

我正在尝试执行 execv() 命令,第二个参数是要传递的参数列表。

我的论点目前以字符串格式保存,即

--config=moo --console --something=moo2 --path="this can have spaces" --format=x

我想做的是把它分成char**参数,即

argv[0] = "--config=moo"
argv[1] = "--console"

我不太明白的是一件事(很抱歉,自从我上次使用 C 以来已经很长时间了)。如果我想构建一个字符串以放入这个 argv 数组中,我该怎么做,例如:-

char* argv[10];
char* myPath = getMyPath();
argv[0] = "--config=moo";
argv[1] = ... ... ... 
...
...
argv[10] = "--path=" + myPath;

我相信这在 C 中是不允许的,因为我必须提前分配所有内存,所以通过将 argv 分配为 10 个元素,我不能再去单独定义每个元素.. 或者我可以吗?

我知道 + 修饰符在 C 中不起作用,但我不确定复制它需要什么函数(我意识到我可以使用 strcat 添加到现有定义的数组,但不认为这适用于新形成的阵列)

4

4 回答 4

1

char buffer[N]您可以 malloc 将使用 strcat() 的内存,或者您可以在堆栈上使用大于需要的内存。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


const char * someFunction();

int main(int argc, char ** argv) {

  const char[] path = "commandName";
  const char[] arg1 = "--config=moo";
  const char[] arg2 = "--console";
  const char[] arg3 = "--something=moo2";
  //arg4 is skiiped
  const char[] arg5 = "--format=x";

  const char * mypath = someFunction();
  const char[] pathprefix = "--path=";

  size_t pathprefixlength = strlen(pathprefix);
  size_t stringlength =  pathprefixlength + strlen(mypath);

  char * arg4 = (char *)malloc(stringlength + 1);

  strcpy(arg4, pathprefix);
  strcpy(arg4 +  pathprefixlength, mypath);

  arg4[stringlength] = '\0'; //null terminate
  char *argvec[7]; // array of pointers
  argvec[0] = path;
  argvec[1] = arg1;
  argvec[2] = arg2;
  argvec[3] = arg3;
  argvec[4] = arg4;
  argvec[5] = arg;
  argvec[6] = NULL;
  //do something with argvec;
  free(arg4);
}
于 2013-04-06T17:22:43.900 回答
1

通用malloc

man malloc可能会有所帮助。malloc占用minimum您需要的内存字节数(即malloc可以选择为您提供更多)。因此,如果您需要数组10中的元素,最好像您已经完成的那样char简单地分配。char* argv[10]但是,这会为 10 个char*尚未定义的容器创建一个容器。因此,对于每个char*argv[0]...argv[9]您都可以准确定义其中的内容。例如,如果你想 malloc 一个大小为 200 的字符串 for argv[0],你可以使用如下语句(注意,200可以保存在常量或变量中):

argv[0] = malloc(200 * sizeof(char));

一般来说,sizeof(char) == 1 byte, 所以这个值可能会尝试获取 200 字节。但是,此时您可以argv[0]按您需要的任何方式进行修改(即strncpystrncat等)。

现在,如果你不知道你可能有多少参数,你可以动态分配你的容器。因此char* argv[10],您可以尝试分配一个char** argv. 为此,您将执行以下语句:

int SOME_SIZE = 1500 ; // Or some dynamic value read, etc.
char** argv = malloc(SOME_SIZE * sizeof(char*));

通常sizeof(char*) == 4 bytes在 32 位系统上(典型指针的大小)。现在你可以使用这块内存,argv,以与之前类似的方式。为了便于思考,malloc以这种方式使用可以让您执行相对等价的char* argv[WITH_SOME_DYNAMIC_NUMBER]. 因此,您可以按照我上面描述的类似方式操作这个新容器。

但是请记住,当您使用完由 创建的内存时malloc,您必须调用free,否则在程序终止之前它不会被释放。

你的问题

如果我正确理解了您的问题,则您有一个扁平的字符串,您想将其转换为execve. 我将制定一个简单的示例,试图解释可以做到这一点的众多方法中的一种。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void someMethod()
{
  char* argv[10];
  char* path = getMyPath();

  // Notice - this is a little messy and can/should be encapsulated away in another
  // method for ease of use - this is to explicitly show, however, how this can work.
  argv[9] = malloc((strlen(path) + strlen("--path=") + 1) * sizeof(char));
  strncpy(argv[9], "--path=", strlen("--path="));
  argv[9][strlen("--path=")] = '\0'; // NULL-terminate since strncpy doesn't
  strncat(argv[9], path, strlen(path));

  // Do stuff with array
  printf("%s\n", argv[9]);

  // Technically, you should never get here if execve succeeds since it will blow this
  // entire program away (unless you are fork()'ing first)
  free(argv[9]);
}
于 2013-04-06T17:53:15.333 回答
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* strcata(char* s1, char* s2){
    char *p;
    p=(char*)malloc(sizeof(char)*(strlen(s1)+strlen(s2)+1));
    if(p == NULL) return NULL;

    *p='\0';

    return strcat(strcat(p, s1), s2);
}

int main(int argc, char *argv[])
{
    char *p;

    p=strcata("--path=", ".:./bin");
    printf("%s\n", p);

   return 0;
}
于 2013-04-06T17:46:34.373 回答
0

您可以使用 malloc 进行动态内存分配

例如,假设我们有以下简单的结构:

struct myRecord {

 char firstName[60];

 char lastName[60];

 int employeeID;

 struct myRecord * nextRecord;

};

struct myRecord * headPtr; // point to first structure in the list
// This line allocates memory for the first record:
headPtr = (struct myRecord *)malloc(sizeof(myRecord));
于 2013-04-06T17:50:04.807 回答