I'm new at c
and I'm writing a script that inputs a file path as arguments. I want to have the last element of the path and the rest of the path.
Here is what I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *file = argv[1];
char base[sizeof(file)] = "";
char *tok = strtok(file, "/");
while (tok != NULL)
{
strcat(base, tok);
tok = strtok(NULL, "/");
}
printf("Base folder: %s\n", base);
printf("Last element: %s\n", tok);
return 0;
}
Input: ./getlast /this/is/some/path/file.txt
Expected result:
Base folder: /this/is/some/path
Last element: file.txt
It gives me this error when I concatenate base
with tok
:
[1] 15245 illegal hardware instruction ./getlast /Users/<myusername>/Desktop/getlast/getlast.c
I keep trying different solutions but I can't figure out what is wrong.
(I haven't a good English so sorry for that)
To use strtok()
for this task would be complicated.
Determining which is the last token (filename) involves not commiting to concatentating until the next token is retrieved from the string.
One could 'hang onto' one pointer and append when another token is found, but that's confusing.
To find what might be called "the last token", strrchr()
is perfectly suited to the task.
I regard "enviroment vars" (like argv) to be readonly, so strdup()
makes a working copy that can be altered with impunity.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main( int argc, char *argv[] ) {
if( argc != 2 ) { // always test before using
printf( "Bad usage\n" );
return;
}
char *copy = strdup( argv[1] ); // temp working copy to manipulate
char *lastSep = strrchr( copy, '/' ); // find LAST slash char
if( lastSep == NULL )
printf( "No prefix path: %s\n", argv[1] );
else {
*lastSep++ = '\0'; // split into two strings
printf( "Base folder: %s\n", copy );
printf( "Last element: %s\n", lastSep );
}
free( copy );
}
Update
You can avoid the overhead of making a working copy by capitalising on some pointer arithmetic and printf()
's length specifiers. Here's another way to achieve the same thing without using the heap:
char *p = "/one/two/three/four.txt";
char *lastSep = strrchr( p, '/' ); // find LAST slash char
if( lastSep == NULL )
printf( "No prefix path: %s\n", p );
else {
printf( "Base folder: %.*s\n", lastSep - p, p );
printf( "Last element: %s\n", lastSep + 1 );
}