Токенизируйте переменную среды и сохраните полученный токен в символе ** - PullRequest
0 голосов
/ 26 сентября 2010

Я пытаюсь создать массив строк, которые представляют каталоги, хранящиеся в переменной PATH.Я пишу этот код на C, но у меня возникают проблемы с работой частей выделения памяти.

char* shell_path = getenv ("PATH");
char* tok = strtok (shell_path, SHELL_PATH_SEPARATOR);
int number_of_tokens = 0, i = 0;

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);
}

Проблема в том, что я не могу понять, как я могу точно знать,сколько памяти выделяется.

Я знаю, что дважды разбиваю строки на строки, и, наверное, глупо делать это, но я открыт для улучшений, если кто-то может найти лучший способсделай это.

Ответы [ 4 ]

1 голос
/ 26 сентября 2010

Просто чтобы дать вам в основном тот же ответ, что и у пользователя user411313 на другом диалекте:

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 );
}
1 голос
/ 26 сентября 2010

Вы можете сделать:

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

Также неправильный способ подсчета number_of_tokens. Вам нужно снова вызвать strtok в цикле, передав ему NULL в качестве 1-го аргумента:

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

}
0 голосов
/ 26 сентября 2010

Вы не должны изменять указатель getenv-return, безопаснее сделать копию. С помощью strtok вы можете уничтожить содержимое таблицы вашей среды.

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 голосов
/ 26 сентября 2010

Поскольку вы уже посчитали количество токенов, вы можете использовать его как количество указателей на символ для выделения:

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

Тогда у вас есть еще одна незначительная проблема: вы используете strtok непосредственно в строке, возвращаемой getenv, что приводит к неопределенному поведению (strtok изменяет строку, которую вы ей передаете, разрешено изменять строку, возвращаемую getenv, поэтому вы получаете неопределенное поведение). Возможно, вы сначала захотите продублировать строку, а затем токенизировать свою копию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...