Skip to content

Instantly share code, notes, and snippets.

@cloud11665
Created January 5, 2022 16:53
Show Gist options
  • Save cloud11665/9e01c22846606e22aebcb226d5095c44 to your computer and use it in GitHub Desktop.
Save cloud11665/9e01c22846606e22aebcb226d5095c44 to your computer and use it in GitHub Desktop.
terminalforlife video response
#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment