2010-09-26 53 views
0

我试图创建一个表示存储在PATH变量中的目录的字符串数组。我正在用C编写这段代码,但是我无法使内存分配部分工作。令牌化一个环境变量并将结果标记保存为char **

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

我遇到的问题是,我想不出我怎么才能知道究竟有多少内存来分配。

我知道我将字符串两次标记为字符串,这对我来说可能是愚蠢的,但如果有人能找到更好的方法来做到这一点,我愿意改进。

回答

1

只给你基本相同的答案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); 
} 
+0

这段代码大部分是正确的。 在realloc中它应该是(i + 1)而不是简单的i。 除了这个答案我觉得是以最好的方式回答我的问题的答案。 非常感谢。 – 2010-09-28 05:57:20

+0

@Varun:哎呀,纠正。 – 2010-09-28 07:51:28

1

你可以这样做:

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

而且你指望的number_of_tokens的方式不正确。您需要再次调用strtok在循环传递NULL作为第一参数:

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

} 
+0

呀,这仅仅是一个错误的编辑代码,使其适合在这里显示,当我做了。不过谢谢。 – 2010-09-28 06:00:00

0

既然你已经算令牌的数量已经,您可以使用它作为指针的数量为char分配:

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

然后你有一个更小问题:您正在使用strtok直接由getenv返回的字符串,从而导致未定义行为(strtok修改你传递给它的字符串,而你不许修改由getenv返回的字符串,以便获取undefi ned行为)。您可能首先需要复制字符串,然后标记您的副本。

0

你不应该改变getenv返回指针,更安全的做一个副本。使用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); 
} 
+1

+1表示您可以分离'result'数组和复制的字符串的分配问题。 -1,因为在'i'上有副作用,你可以简单地选择它作为循环变量。 – 2010-09-26 08:31:55