在C语言中获取文件扩展名

7

假设有一个名为12345.jpg的文件。在C语言中,我该如何获取文件扩展名以便与一些文件扩展名进行比较?如果有内置函数,请告诉我。


SO 290488涵盖了很多相同的内容。 - Jonathan Leffler
那么这就是 - https://dev59.com/jXVD5IYBdhLWcg3wNYxZ - Ofek Shilon
可能是在C中获取文件扩展名的重复问题。 - nibot
SO 51949是一个关于C++的问题,由Ofek Shilon提出。然而,其中的答案并不适用于C语言。SO 5309471则是在一年后由nibot提出的问题,但它与前者有交叉引用。[YT]提到的[SO 290488]标记了C++和C两种语言,但它所展示的代码是纯C的(根据目测,我认为这段代码也可以在C++中编译通过,但没有进行测试)。 - Jonathan Leffler
4个回答

10

一个函数来实现这个功能,同时附带一个测试套件:

#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;
}

使用以下方式运行:

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

提供给你:

[abc] - > []
[abc.] - > [.]
[abc.1] - > [.1]
[.xyz] - > [.xyz]
[abc.def] - > [.def]
[abc.def.ghi] - > [.ghi]

对于 strrchr,加一分。这是在字符串中查找最后一个字符的最佳方法。 - tomlogic
以防有人错过了。getExt()假设fspec是一个基本名称,而不是完整路径。例如,考虑my.dir/file。使用basename()从完整路径中获取基本名称。 - Michael Closson

6

很可能是:

#include <string.h>

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

这将为您提供延期的指针,如果没有延期,则提供空指针。您可能需要做更多的尽职调查,以确保在点号后面没有斜杠等其他内容。


3
strrchr(filename+1,'.'); 可以处理以点开头但没有扩展名的名称,例如 .svn - drawnonward
@drawnonward - 毫无疑问,如果您将其视为没有名称的扩展名而不是没有扩展名的文件名,则这是另一个需要考虑的“尽职调查”案例。然而,如果OP想要将找到的扩展名与已知扩展名的相对较短列表进行比较,那么.svn不在列表中的事实可能并不重要。 - Jonathan Leffler
@drawnonward:我误读了你的意思-你说得很有道理。然而,这对于以“/”开头的绝对路径名或包含斜杠的相对名称(例如“subdir/.svn”)是没有帮助的。可以说需要找到文件基本名称的起始位置(最后一个斜杠后面),然后查找第一个位置不在点中的点。我想这意味着父目录'..'的名称为'dot',后跟以点开头且没有其他内容的扩展名......通常还会出现另一种曲线球需要处理。 - Jonathan Leffler
@drawnonward 如果文件名为空字符串,则可能导致分段错误。 - syockit

2

有一个便携式CRT解决方案:_splitpath

在Windows中还有一个未记录的shell32 API叫做PathGetExtension,但是它在很多方面都是邪恶的,所以我可能不应该提到它。


6
这显然是我之前不知道的“便携”这个词的新定义 :-) 对于 HHGTTG 的道格拉斯 · 亚当斯,我表示歉意。 - paxdiablo
4
确实,从来没有见过“便携式”这个词和 MSDN 链接在同一个句子中 :-) - mtvec
2
我的错,我的错!不会编辑答案,让其他人也能享受 :) - Ofek Shilon
嗯,是的,答案仍然有用,所以我不会编辑它。如果您使用的是 MS 平台,最好使用 _splitpath 而不是编写自己的代码(例如在我的答案中)。 - paxdiablo
当然 - 我考虑过删除“便携式”(我的脑子到哪里去了呢?),但最终还是放弃了。 - Ofek Shilon

-1
使用strchr函数 第一个数组成员将给你文件名 第二个数组成员将给你扩展名

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接