Parse $PATH variable and save the directory names into an array of strings
bash, c, gcc, malloc, strtok
Solution
2 main things wrong with your code, pretty much summarized by the comments:
- you strtok a public buffer (returned by `getenv`)
- you don't know how many variables will be in the buffer so you don't allocate the array of arrays at all!
Let me propose a working implementation not using strtok, and thus allowing to detect empty path (and replace it by `.` as Jonathan hinted). Compiles without any warnings using `gcc -Wall -Wwrite-strings`:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
const char **array;
const char *orig_path_var = getenv("PATH");
char *path_var = strdup(orig_path_var ? orig_path_var : ""); // just in case PATH is NULL, very unlikely
const char *the_dot = ".";
int j;
int len=strlen(path_var);
int nb_colons=0;
char pathsep = ':';
int current_colon = 0;
// first count how many paths we have, and "split" almost like strtok would do
for (j=0;j<len;j++)
{
if (path_var[j]==pathsep)
{
nb_colons++;
path_var[j] = '\0';
}
}
// allocate the array of strings
array=malloc((nb_colons+1) * sizeof(*array));
array[0] = path_var; // first path
// rest of paths
for (j=0;j<len;j++)
{
if (path_var[j]=='\0')
{
current_colon++;
array[current_colon] = path_var+j+1;
if (array[current_colon][0]=='\0')
{
// special case: add dot if path is empty
array[current_colon] = the_dot;
}
}
}
for (j=0;j<nb_colons+1;j++)
{
printf("Path %d: <%s>\n",j,array[j]);
}
return(0);
}
Details of the operations:
- make a copy of the env string to avoid butchering it
- count the colons (to make it work with windows, just replace with `;`) and tokenize
- allocate the array according to number of colons + 1 (1 more token than number of separators!)
- second pass to go through the string again and fill it with parts of the tokenized string (no need to allocate again, the original string is already allocated)
- special case: empty path: replace by `.`. Could display a warning to tell the user that this is not safe.
- print the result
Problem
I want to parse the $PATH variable of Linux, and then save the directory names that are getting separated with ':' into an array of strings. I know it's a simple task but I am stuck and any help would be nice. My code so far is something like this but something ain't right. ``` char **array; char *path_string; char *path_var = getenv("PATH"); int size_of_path_var = strlen(path_var); path_string = strtok(path_var, ":"); while (path_string != NULL) { ss = strlen(path_string) array[i] = (char *)malloc(ss + 1); array[i] = path_string; //this is actually all i want to do for every path i++; path_string = strtok(NULL, ":"); } ```