如何从C中的字符串中剥离文件扩展名?

时间:2017-04-02 01:19:06

标签: c string replace split

如何从C中的字符串中剥离文件扩展名?

例如,

如果我的文件名包含文件扩展名

  

hello.txt的

     

的hello.c

     

hello.java

应该只产生没有扩展名的文件名

  

您好

文件扩展名的长度不重要。

该功能也应该是便携式的,并且取决于系统。

我知道如何使用strchrstrrchr获取文件扩展名。我已经在Bash和Python中完成了这项工作,但我从来没有在C中这样做。

注意:这是个人练习,有助于加强我对C编程语言的理解。

4 个答案:

答案 0 :(得分:5)

我不知道有最好的方法,但这是一种方法。大概你不想从点文件中删除名称。此外,您可能只想删除最后一个点到字符串末尾的字符。请注意,在下面的代码中,输入字符串被修改,因此文件名不能是字符串文字,但必须是以空字符结尾的字符数组。

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

void strip_ext(char *);

int main(void)
{
    char filename1[] = "myfile.txt";
    char filename2[] = ".emacs";
    char filename3[] = "anotherfile.";
    char filename4[] = "nodot";
    char filename5[] = "";
    char filename6[] = "dot.dot.dot";

    strip_ext(filename1);
    strip_ext(filename2);
    strip_ext(filename3);
    strip_ext(filename4);
    strip_ext(filename5);
    strip_ext(filename6);

    printf("file1: %s\n", filename1);
    printf("file2: %s\n", filename2);
    printf("file3: %s\n", filename3);
    printf("file4: %s\n", filename4);
    printf("file5: %s\n", filename5);
    printf("file6: %s\n", filename6);

    return 0;
}

void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.') {
        --end;
    }

    if (end > fname) {
        *end = '\0';
    }
}

节目输出:

file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5: 
file6: dot.dot

更新

@David C. Rankin指出更复杂的文件路径可能会使问题复杂化。下面是对strip_ext()函数的修改,当遇到正斜杠或反斜杠时停止查找点,在这种情况下文件名字符串保持不变:

void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.' && *end != '\\' && *end != '/') {
        --end;
    }
    if ((end > fname && *end == '.') &&
        (*(end - 1) != '\\' && *(end - 1) != '/')) {
        *end = '\0';
    }  
}

使用相同的测试字符串和其他测试字符串运行此函数:

char filename7[] = "/my.dir/myfile";
char filename8[] = "/dir/.filename";

生成此输出:

file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5: 
file6: dot.dot
file7: /my.dir/myfile
file8: /dir/.filename

答案 1 :(得分:0)

可能有很多方法可以做到这一点。一种方法是用空字符(\0)替换第一个点。

char [] filename = "Hello.java";

for(int i=0;i<strlen(filename);i++) {
   if(filename[i] == '.') {
       filename[i]='\0';
       break;
   }
}

答案 2 :(得分:0)

这可能不是最好的方法,但可能的解决方案是在点的位置放置一个NULL终止符,这可以通过以下代码实现。

char *filename_dot = strchr(filename, '.');
int offset = filename_dot - filename;
filename[offset] = '\0';

答案 3 :(得分:0)

const char * s_name // pointing to ex "myString.ext"

char * s_atext = strstr(s_name, ".ext");
if (s_atext != NULL) {
    /* Extract the filename without extension in case only */
    size_t name_only_size = s_atext - s_name;
    char * s_name_only = strndup(s_name, name_only_size); 
    // use your s_name_only
    printf("FileName w/o ext: %s\n", s_name_only);
    if (s_name_only) free(s_name_only);
}