7

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
boom
  • 5,856
  • 24
  • 61
  • 96
  • [SO 290488](http://stackoverflow.com/questions/290488) covers a lot of the same ground. – Jonathan Leffler Jun 14 '10 at 06:13
  • So is this - http://stackoverflow.com/questions/51949/how-to-get-file-extension-from-string-in-c – Ofek Shilon Jun 14 '10 at 06:46
  • Possible duplicate of [Getting file extension in C](http://stackoverflow.com/questions/5309471/getting-file-extension-in-c) – nibot Mar 04 '17 at 18:15
  • [SO 51949](http://stackoverflow.com/q/51949/), mentioned by [Ofek Shilon](https://stackoverflow.com/users/89706/ofek-shilon), is a C++ question. The answers are not appropriate for C. [SO 5309471](http://stackoverflow.com/q/5309471/), mentioned by [nibot](https://stackoverflow.com/users/462335/nibot), was asked a year or so after this. There's a cross-reference back to this question, though. SO 290488, mentioned by YT, is tagged with both C++ and C, though the code it shows is pure C (that would also compile in C++, I think, based on eyeballing, not on testing it). – Jonathan Leffler Nov 28 '22 at 22:50

4 Answers4

10

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
  • 854,327
  • 234
  • 1,573
  • 1,953
  • +1 for `strrchr`. Best method for finding the last instance of a character in a string. – tomlogic Jun 14 '10 at 19:14
  • Just in case anyone misses it. `getExt()` assumes that `fspec` is a basename, not full path. Consider for e.g., `my.dir/file`. Use `basename()` to get the basename from a full path. – Michael Closson Nov 12 '13 at 01:07
6

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
  • 730,956
  • 141
  • 904
  • 1,278
  • 3
    `strrchr(filename+1,'.');` would handle names like `.svn` that start with a dot but have no extension. – drawnonward Jun 14 '10 at 06:42
  • @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 Jun 14 '10 at 06:54
  • @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 Jun 14 '10 at 21:04
  • @drawnonward Might cause segmentation fault if filename is empty string. – syockit Jun 03 '16 at 01:31
2

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
  • 14,734
  • 5
  • 67
  • 101
  • 6
    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 Jun 14 '10 at 06:32
  • 4
    Indeed, never seen the word "portable" and a link to msdn in the same sentence:-) – mtvec Jun 14 '10 at 06:38
  • 2
    My bad, my bad! Won't edit the answer, for others to enjoy :) – Ofek Shilon Jun 14 '10 at 06:42
  • 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 Jun 14 '10 at 06:48
  • Of course - I considered removing 'portable' (where was my head, really?) but dropped it. – Ofek Shilon Jun 14 '10 at 07:07
-1

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

Shrikant
  • 39
  • 1