Today I needed to work with some paths in C99 and I couldn't find good solutions to it if any, so I made my own, here's a small set of functions you can use to work with paths and path-like strings :)
Also I haven't really optimised it so like, if you want to please do optimise it and post it to CaO :)
(BTW this can probably be made to work with C89, but as I am using C99 in this example I don't mind it lol, you can convert it quite easily :))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 | #include <string.h>
#include <stdlib.h>
/*
* Chop a string from index `begin` to index `end`
* returns a `malloc` pointer casted to `char *`,
* meaning don't forget to `free()` it
*/
const char *
chop_str(const char *str, const unsigned long begin, const unsigned long end) {
if (begin >= end)
return NULL;
char *buf = (char *)malloc((sizeof str[0]) * (end - begin) + 1);
unsigned long idx;
for (idx = begin; idx <= end; ++idx)
buf[idx - begin] = str[idx];
buf[idx] = '\0';
return buf;
}
/*
* Remove trailing char(s) `chr` (if any) from a a string `str` of length
* `len`, this function returns a `malloc()` pointer, don't forget to `free()`
* it
*/
const char *
remove_ntrailing(const char *str, const unsigned long len, const char chr) {
char *cpy = (char *)malloc(((sizeof str[0]) * len) + 1);
strncpy(cpy, str, len); // NOLINT
for (unsigned long idx = len - 1; idx > 0; --idx)
if (cpy[idx] == chr)
cpy[idx] = '\0';
else
break;
return cpy;
}
#define remove_trailing(str, chr) remove_ntrailing(str, strlen(str), chr)
/*
* Get base path of path `path` which is the length of `len`,
* this is a wrapper around `chop_str()`, which returns a `malloc`
* pointer, don't forget to free it
*/
const char *get_nbase(const char *path, const unsigned long len) {
unsigned long last_slash = 0;
for (unsigned long idx = 0; idx < len; ++idx) {
if (path[idx] == '/')
last_slash = idx;
}
return chop_str(path, last_slash + 1, strlen(path));
}
#define get_base(path) get_nbase(path, strlen(path))
#define get_bbase(path) get_base(remove_trailing(path, '/'))
|
The macros are optional, just some nice wrappers, anyway, enjoy :)