开发者

Tokenize an environment variable and save the resulting token in a char**

开发者 https://www.devze.com 2023-01-17 09:48 出处:网络
I\'m attempting to create an array of strings that represent the directories stored in the PATH variable. I\'m writing this code in C, but I\'m having trouble getting the memory allocation parts worki

I'm attempting to create an array of strings that represent the directories stored in the PATH variable. I'm writing this code in C, but I'm having trouble getting the memory allocation parts working.

char* shell_path = getenv ("PATH");
char* tok = strtok (shell_path, SHELL_PATH_SEPARATOR);
int number_of_tokens = 0, i = 0;开发者_Go百科

while (tok != NULL)
{
    number_of_tokens++;
}

Shell_Path_Directories = malloc (/* This is where I need some help */);
shell_path = getenv ("PATH");
tok = strtok (shell_path, SHELL_PATH_SEPARATOR);
while (tok != NULL)
{
    Shell_Path_Directories[i++] = tok;
    tok = strtok (NULL, SHELL_PATH_SEPARATOR);
}

The issue I'm having is that I can't think of how I can know exactly how much memory to allocate.

I know I'm tokenizing the strings twice, and that it's probably stupid for me to be doing that, but I'm open to improvements if someone can figure out a better way to do this.


Just to give you basically the same answer as user411313's in a different dialect:

char* shell_path = getenv ("PATH");

/* Copy the environment string */
size_t const len = strlen(shell_path)+1;
char *copyenv = memcpy(malloc(len), shell_path, len);

/* start the tokenization */
char *p=strtok(copyenv,SHELL_PATH_SEPARATOR);
/* the path should always contain at least one element */
assert(p);

char **result = malloc(sizeof result[0]);
int i = 0;

while (1)
{
  result[i] = strcpy(malloc(strlen(p)+1), p);
  p=strtok(0,SHELL_PATH_SEPARATOR);
  if (!p) break;
  ++i;
  result = realloc( result, (i+1)*sizeof*result );
}


You can do:

Shell_Path_Directories = malloc (sizeof(char*) * number_of_tokens);

Also the way you are counting the number_of_tokens is incorrect. You need to call the strtok again in the loop passing it NULL as the 1st argument:

while (tok != NULL) {
    number_of_tokens++;
    tok = strtok (NULL, SHELL_PATH_SEPARATOR);

}


Since you've counted the number of tokens already, you can use that as the number of pointers to char to allocate:

char **Shell_Path_Directories = malloc(number_of_tokens * sizeof(char *));

Then you have one more minor issue: you're using strtok directly on the string returned by getenv, which leads to undefined behavior (strtok modifies the string you pass to it, and you're not allowed to modify the string returned by getenv, so you get undefined behavior). You probably want to duplicate the string first, then tokenize your copy instead.


You should not change the getenv-return pointer, safer you make a copy. With strtok you can destroy the content of your environment table.

char* shell_path = getenv ("PATH");
char *p,*copyenv = strcpy( malloc(strlen(shell_path)+1), shell_path );
char **result = 0;
int i = 0;
for( p=strtok(copyenv,SHELL_PATH_SEPARATOR); p; p=strtok(0,SHELL_PATH_SEPARATOR) )
{
  result = realloc( result, ++i*sizeof*result );
  strcpy( result[i-1]=malloc(strlen(p)+1), p );
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号