Pelles C forum

C language => Tips & tricks => Topic started by: TimoVJL on April 27, 2012, 09:46:36 PM

Title: basename ext
Post by: TimoVJL on April 27, 2012, 09:46:36 PM
Code: [Select]
#include <stdio.h>

char *FindLast(char *s, char c)
{
char *p, *p2 = 0;
for(p=s; *p; p++)
if (*p == c) p2 = p;
if (p2) p2++;
else if (c == '\\') return s;
return p2;
}

int main(int argc, char **argv)
{
char *name = "C:\\WINDOWS\\system32\\kernel32.dll";
//char *name = "kernel32.dll";
printf("%s %s %s\n", name, FindLast(name, '\\'), FindLast(name, '.'));
return 0;
}
Title: Re: basename ext
Post by: CommonTater on April 27, 2012, 10:26:29 PM
Nice snippet!

Also if you include shlwapi.h you can use PathFindFileName() when working in WinAPI.

Title: Re: basename ext
Post by: TimoVJL on April 27, 2012, 10:36:08 PM
No, if i think size of code  ;D
Title: Re: basename ext
Post by: CommonTater on April 27, 2012, 10:58:08 PM
No, if i think size of code  ;D

True... linking into a huge DLL isn't always the best plan... But if you've got it loaded *anyway* ;)
Title: Re: basename ext
Post by: TimoVJL on April 27, 2012, 11:07:41 PM
actually shlwapi.dll is quite small, only about 350 kb.
But what about to kill two flies with one beat (function)  :)
Title: Re: basename ext
Post by: CommonTater on April 28, 2012, 03:53:31 AM
actually shlwapi.dll is quite small, only about 350 kb.
But what about to kill two flies with one beat (function)  :)

LOL... Yep, like I said... Nice snippet! ....
Title: Re: basename ext
Post by: czerny on April 28, 2012, 11:34:38 AM
Code: [Select]
char *FindLast(char *s, char c)
{
char *p=s;
while(*p++);
while(--p>s)
if(c==*p) return ++p;
return c=='\\' ? s : 0;
}

Don't know if it is not quicker reverse?

czerny
Title: Re: basename ext
Post by: TimoVJL on April 28, 2012, 12:19:05 PM
It is better than mine.
Title: Re: basename ext
Post by: Vortex on April 28, 2012, 12:25:54 PM
Hi timovjl,

Searching for both of the dot and slash is a good idea. Maybe, you can create a lookup table to perform a faster search.
Title: Re: basename ext
Post by: JohnF on April 28, 2012, 02:42:30 PM
A little more care is needed if the filename does not have an extension and path has a period '.' embedded. I had this situation recently.

e.g.

char * name = "C:\\a.folder\\tem\\thefile";

John

Title: Re: basename ext
Post by: czerny on April 28, 2012, 03:14:29 PM
Quote
A little more care is needed if the filename does not have an extension and path has a period '.' embedded. I had this situation recently.

You are right, if the function should find basename and extension.

But if it should find last appearance of character c it should even be shorter:

Code: [Select]
char *FindLast(char *s, char c)
{
char *p=s;
while(*p++);
while(--p>s)
if(c==*p) return ++p;
return 0;
}

It can be followed by some  tests:

Code: [Select]
b=FindLast(path,'\\');
e=FindLast(path,'.');

if (!b) ...
if (!e) ...
if (e<b) ...
Title: Re: basename ext
Post by: JohnF on April 28, 2012, 03:48:59 PM
Yes.

I posted because the example was for basename and ext.

John
Title: Re: basename ext
Post by: TimoVJL on April 28, 2012, 04:37:06 PM
Code: [Select]
char *FindLast(char *s, char c)
{
char *p=s;
while(*p++);
while(--p>s) {
if(*p=='\\' && c=='.') return 0;
if(c==*p) return ++p;
}
return c=='\\' ? s : 0;
}
Title: Re: basename ext
Post by: czerny on May 07, 2012, 10:33:10 PM
Hallo,

is there a good reason to use the api function PathMatchSpec compared with the following  PathMatchSpec2

Code: [Select]
BOOL PathMatchSpec2(char *fn, char *ext)
{
return !strcmp(FindLast(fn,'.'),ext);
}

PathMatchSpec(fn,"*.txt");
PathMatchSpec2(fn,"txt");

czerny
Title: Re: basename ext
Post by: CommonTater on May 07, 2012, 10:55:56 PM
Hallo,

is there a good reason to use the api function PathMatchSpec compared with the following  PathMatchSpec2

Code: [Select]
BOOL PathMatchSpec2(char *fn, char *ext)
{
return !strcmp(FindLast(fn,'.'),ext);
}

PathMatchSpec(fn,"*.txt");
PathMatchSpec2(fn,"txt");

czerny

That works if you're looking for a specific extension....

You can also use PathFindFilename() and PathFindExtension() to search your strings.  I use them fairly often and so long as you're careful to check whether it's a file in advance ( using PathIsDirectory() ) it gives very good results.



Title: Re: basename ext
Post by: czerny on May 07, 2012, 11:32:51 PM
This should be a little bit quicker
Code: [Select]
BOOL PathMatchSpec3(char *fn, char *ext)
{
char *p=fn, *q=ext;
while (*p++);
while (*q++);

while (--q>=ext)
if (*--p != *q) return FALSE;
return (*--p == '.');
}