#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *env = getenv("PATH"); int cnt = 1, i = 0; // just a fancy way of counting the number of ':' characters in a string. // we start off with the char pointer `p`, pointing to the beggining of `env` // and we do the third part of the for loop (cnt+=*p++==':'), for as long as // `*p`, which also means `*p != '\0'`, because strings are terminated by '\0'. // The third part may be more readable when we add parens to it: // `cnt += (*(p++) == ':')` // so. we increment `cnt` by `(*(p++) == ':')`, which means 1 when `*p == ':'`, // and 0 when it doesn't. `*p++` is just a way of saying: "give me the value // at `p`, and then increment" for (char *p = env; *p; cnt+=*p++==':'); // ok, we now have the number of ':' characters + 1 in the variable `cnt`. // strok is explained here: https://stackoverflow.com/a/23456549/12954733 char *ptr = strtok(env, ":"); // we reserve an array of strings for every subpath in $PATH char **arr = malloc(cnt * sizeof(char*)); // the string ptr looks something like this: // "/usr/bin\0/usr/local/sbin:/bin:..." // notice the NULL byte '\0' which was a ':', but was replaced by strtok. // now we are just assigning a pointer into the original `env` string // to the i-th index of the array, and calling strtok to replace another ':' // with a '\0' do { arr[i++] = ptr; } while(ptr = strtok(NULL, ":")); // now, our `env` string, and the `arr` array looks something like this: // env: "/usr/bin\0/usr/local/sbin\0/home/foo/.local/bin\0/bin" // ^ ^ ^ ^ // arr[0] arr[1] arr[2] arr[3] // the string hasn't moved anywhere, and we are just using the fact that a // string must be NULL terminated, so when we do something like // `printf("%s", arr[0])`, it goes only to the closes null byte to the right // print out the array to confirm. for (int j = 0; j < i; j++) { printf("arr[%d] = '%s'\n", j, arr[j]); } return 0; }