2

Let's say I have the following string which looks like a file path:

 char *filepath = "this/is/my/path/to/file.jpg";

I can use strrchr() to extract file.jpg as follows:

 char *filename =  strrchr(filepath, '/') + 1;

Now I need to extract and store the rest of the string this/is/my/path/to. How do I do that in the most effective manner? Please note that I would like to avoid using strtok()or regex or big iterative loops.

It will be very nice if:

I can apply the same the substring extraction technique to strchr() where I have extracted the substring this using strchr(filepath, '/') and now I need to extract the rest of the substring is/my/path/to/file.jpg

blackbeard
  • 385
  • 2
  • 12
  • 2
    Just copy the first (filename - filepath) characters to a new location and append a _null character_. Some additional work needed for the `'/'` seperator, if found. Yet the post is too unclear for details. Post what you are tried to do. Watch out for escape sequences in `"this/is/my/path/to/file.jpg"`. – chux - Reinstate Monica May 06 '18 at 03:21
  • 2
    @chux:I would like to use `filename` and `filepath` variables to store rest of the substring in `directory_path` so that if I do a `printf("%s\n", directory_path)`, the output is `this/is/my/path/to`. Could you please show me how would you code " copy the first (filename - filepath) characters to a new location "? – blackbeard May 06 '18 at 03:40

2 Answers2

2

Copy everything up to the file name, then append a '\0' :

int   pathLen = filename - filepath;
char *path = (char *) malloc(pathLen + 1);
memcpy(path, filepath, pathLen);
path[pathLen] = '\0';

...

free(path);
Sid S
  • 6,037
  • 2
  • 18
  • 24
  • To stay on the save side make `pathLen` a `size_t` or even better `ptrdiff_t`. – alk May 06 '18 at 07:18
  • 1
    Also in C there is no need to cast the result of `malloc()`. – alk May 06 '18 at 07:18
  • @alk, The cast is there to get rid of compiler warnings. – Sid S May 06 '18 at 07:21
  • There should not be any warnings **in C**. If there were, something else is wrong. – alk May 06 '18 at 07:23
  • @aik, It may depend on your compiler and your chosen warning level. Either way, what do you perceive as harmful about being explicit ? – Sid S May 06 '18 at 07:24
  • 1
    No, any decent C compiler shall not issue a warning, at no level. If it does it's either no C compiler, or it's elder then 30 years, or it's broken. – alk May 06 '18 at 07:26
  • 1
    Further any cast whose purpose is "to get rid of compiler warnings" is dangerously mismotivated. – R.. GitHub STOP HELPING ICE May 06 '18 at 12:21
  • The code as written above is valid C and C++. Removing the cast makes it invalid C++ and hence the code becomes less portable by removing the cast. – Sid S May 06 '18 at 20:46
0

If your string is in writable memory (ie, not a string literal) you can do this

char *p =  strrchr(filepath, '/');
*p = '\0';
char *filename = p + 1;

this will give you filepath pointing at "this/is/my/path/to" and filename pointing at "file.jpg". Without any copying.

Cmaster
  • 72
  • 1
  • 3
  • 1
    Not just "in writable memory" but "acceptable to write per your program's contracts of object ownership & mutability". – R.. GitHub STOP HELPING ICE May 06 '18 at 12:24
  • As per the OP's code `filepath` points to string literal which's elements may not be changed. So this `*p = '\0';` statement mostly likely will end the program. – alk May 19 '18 at 09:45