"Kieran Simkin" <ki****@digit al-crocus.com> writes:
"Joe Laughlin" <Jo************ ***@boeing.com> wrote in message
news:Hy******** @news.boeing.co m... > Joe Laughlin wrote:
>> If I have a character array with
>> "/some/file/directory/file_name", are there any
>> functions / libraries that I could use to separate the
>> directory ("some/file/directory") from the file name
>> ("file_name" ).
>>
>> I looked at sscanf(), but that didn't seem to do what I
>> wanted.
I'm not familar with C character array processing, sorry. Again, are
there any standard libraries that would let me scan backwards, or do
I need to do this manually?
There may be a library function that'll do this for you, but it's quite
quick to do it manually too. See the example below:
void extractfilename (const char *path, char *filename) {
int i,c=0;
/* put the highest value for n in path[n] into i (if we ignore
the \0) */
i=strlen(path)-1;
/* itterate backwards through the array decreasing i until we get
to a '/' */
while (i>0) {
if (path[i] == '/')
break;
i--;
}
/* itterate forwards through the array starting from the element
after after the '/' and dump the remaining characters into
filename */
while (i<strlen(path) ) {
filename[c++]=path[++i];
}
}
I wrote this to test my own knowledge more than anything, comments
invited. A better version of the function would take the size of the
destination array as an argument to avoid buffer overflows but I left
this out for simplicity. Code compiles without warnings in gcc with
-Wall -pedantic.
Three comments:
- `int' does not necessarily have a large enough range to represent
the size of an object. Better use `size_t', the type returned
by `strlen'. However, if you just change `int' to `size_t' (an
/unsigned/ type), your algorithm won't work anymore - think about
what happens when `path' is an empty string.
- Your algorithm is inefficient in that it first scans the complete
string to find its end (strlen), and then scans part of the string
/again/ to find the last slash. This can be avoided by scanning the
string once and in the process remembering the last slash encountered.
- It is also inefficient to call `strlen (path)' in the while loop.
Unless the compiler recognizes that it can optimize this by moving the
`strlen' call out of the loop, the string will be scanned once for
every iteration!
#include <stdio.h>
/* Undefined behavior if `path' is a null pointer, or if `filename'
doesn't point to a large enough buffer. Return `filename'. */
char *extractfilenam e (const char *path, char *const filename)
{
/* Pointer the first character that should be copied. */
const char *src = path;
/* Pointer to the buffer where the filename should be copied. */
char *dst = filename;
while (*path != '\0')
{
/* Increment `path' and look for a slash. */
if (*path++ == '/')
{
/* If a slash has been found, `path' has already been
incremented, so that `src' points one past the slash. */
src = path;
}
}
/* Copy remaining characters. */
while (*dst++ = *src++)
continue;
return filename;
}
int main (void)
{
const char *test1 = "/path/and/filename";
const char *test2 = "filename_witho ut_path";
const char *test3 = "/trailing/slash/";
const char *test4 = "";
char buffer [22];
printf ("test1: \"%s\" -> \"%s\"\n", test1, extractfilename (test1, buffer));
printf ("test2: \"%s\" -> \"%s\"\n", test2, extractfilename (test2, buffer));
printf ("test3: \"%s\" -> \"%s\"\n", test3, extractfilename (test3, buffer));
printf ("test4: \"%s\" -> \"%s\"\n", test4, extractfilename (test4, buffer));
return 0;
}
Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- )
http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/