tags:

views:

116

answers:

4

Say there is a file called 12345.jpg. In C, how can I get the file extension so that I can compare with some file extension? If there are any inbuilt functions, kindly please let me know.

+5  A: 

Probably:

#include <string.h>

char *extn = strrchr(filename, '.');

That will give you a pointer to the period of the extension, or a null pointer if there is no extension. You might need to do some more due diligence to ensure that there isn't a slash after the dot, amongst other things.

Jonathan Leffler
`strrchr(filename+1,'.');` would handle names like `.svn` that start with a dot but have no extension.
drawnonward
@drawnonward - indubitably, if you consider that to be a file name with no extension, rather than as an extension with no name. That is another of the 'due diligence' cases to be considered. However, if the OP is looking to compare the found extension with a fairly short list of known extensions, then the fact that `.svn` is not in the list means it probably won't matter anyway.
Jonathan Leffler
@drawnonward: I misread what you were saying - you make a valid point. However, that wouldn't help with absolute pathnames which start with a '/', or relative names containing a slash (`subdir/.svn`). There's a case for saying you need to find the start of the basename of the file (after the last slash, but you have to worry about trailing slashes and root) and then look for a dot not in the first position. I guess that means the parent directory '..' has the name 'dot' followed by an extension starting with a dot and nothing more...There's usually another curve ball to deal with.
Jonathan Leffler
A: 

Use strchr First array member will give you filename Second array member will give you extension

Shrikant
Can you elaborate on this?
Jonathan Leffler
Don't forget a filename like `this.uses.many.periods.jpg`
R Samuel Klatchko
+3  A: 

A function to do that, along with a test harness:

#include <stdio.h>
#include <string.h>

const char *getExt (const char *fspec) {
    char *e = strrchr (fspec, '.');
    if (e == NULL)
        e = ""; // fast method, could also use &(fspec[strlen(fspec)]).
    return e;
}

int main (int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
        printf ("[%s] - > [%s]\n", argv[i], getExt (argv[i]));
    }
    return 0;
}

Running this with:

./program abc abc. abc.1 .xyz abc.def abc.def.ghi

gives you:

[abc] - > []
[abc.] - > [.]
[abc.1] - > [.1]
[.xyz] - > [.xyz]
[abc.def] - > [.def]
[abc.def.ghi] - > [.ghi]
paxdiablo
+1 for `strrchr`. Best method for finding the last instance of a character in a string.
tomlogic
+2  A: 

There's a portable CRT solution: _splitpath.

In windows there's also an undocumented shell32 API called PathGetExtension, but that's evil in so many ways that I probably shouldn't have noted that.

Ofek Shilon
This is obviously some new definition of the word "portable" of which I was previously unaware :-) With apologies to Douglas Adams of HHGTTG fame.
paxdiablo
Indeed, never seen the word "portable" and a link to msdn in the same sentence:-)
Job
My bad, my bad!Won't edit the answer, for others to enjoy :)
Ofek Shilon
Well, yeah, the answer is still useful so I wouldn't edit it. If you're on an MS platform, it's probably preferable to use `_splitpath` than write your own (such as in my answer).
paxdiablo
Of course - I considered removing 'portable' (where was my head, really?) but dropped it.
Ofek Shilon