How to Get File Extension from String in C++

Getting file extension in C

const char *get_filename_ext(const char *filename) {
const char *dot = strrchr(filename, '.');
if(!dot || dot == filename) return "";
return dot + 1;
}

printf("%s\n", get_filename_ext("test.tiff"));
printf("%s\n", get_filename_ext("test.blah.tiff"));
printf("%s\n", get_filename_ext("test."));
printf("%s\n", get_filename_ext("test"));
printf("%s\n", get_filename_ext("..."));

How do I strip a file extension from a string in C?

I don't know that there is a best way, but here is one way. Presumably you don't want to strip the name from dot files. Also, you probably only want to remove the characters from the last dot to the end of the string. Note that in the code below, the input string is modified, so the filename can't be a string literal, but must be a null-terminated character array.

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

Program output:

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

Update

@David C. Rankin has pointed out that more complex filepaths may complicate matters. Below is a modification to the strip_ext() function that stops looking for a dot when either a forward or back slash is encountered, in which case the filename string remains unchanged:

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

Running this function with the same test strings, and the additional test strings:

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

generates this output:

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

Extract the file name and its extension in C

Regarding your actual code (all the other answers so far say to scrap that and do something else, which is good advice, however I am addressing your code as it contains blunders that it'd be good to learn about in advance of next time you try to write something).

Firstly:

strncpy(str, result, (size_t) (last-str) + 1);

is not good. You have dest and src around the wrong way; and further this function does not null-terminate the output (unless the input is short enough, which it isn't). Generally speaking strncpy is almost never a good solution to a problem; either strcpy if you know the length, or snprintf.

Simpler and less error-prone would be:

snprintf(result, sizeof result, "%.*s", (int)(last - str), str);

Similary in the other function,

snprintf(result, sizeof result, "%s", last + 1);

The snprintf function never overflows buffer and always produces a null-terminated string, so long as you get the buffer length right!

Now, even if you fixed those then you have another fundamental problem in that you are returning a pointer to a buffer that is destroyed when the function returns. You could fix ext by just returning last + 1, since that is null-terminated anyway. But for filename you have the usual set of options:

  • return a pointer and a length, and treat it as a length-counted string, not a null-terminated one
  • return pointer to mallocated memory
  • return pointer to static buffer
  • expect the caller to pass in a buffer and a buffer length, which you just write into

Finally, returning NULL on failure is probably a bad idea; if there is no . then return the whole string for filename, and an empty string for ext. Then the calling code does not have to contort itself with checks for NULL.

How to get file extension from string in C++

You have to make sure you take care of file names with more then one dot.
example: c:\.directoryname\file.name.with.too.many.dots.ext would not be handled correctly by strchr or find.

My favorite would be the boost filesystem library that have an extension(path) function

Get a file's extension with C

You can't compare strings like that, that way you're using is pointer comparison...

This is the correct version:

if (strcmp(getFileNameExtension(filename), ".txt") == 0)

I would suggest reading more on C strings.

Also, a highlight for googlers:

What if the filename have multiple "extensions"? Use e.g. strrchr to get the last dot. – Joachim Pileborg

How can I check the file extensions in c?

point != "\0" compares a pointer to another pointer, which is not what you want.

You want to compare whatever point points to , to a char with the value 0. So use e.g.

*point != '\0'; 

Note, if you want to find the end of the string, you could also do

point = file_name + strlen(filename); 

If you want to check whether a string ends in .csv, you could also do something like

if((point = strrchr(filename,'.')) != NULL ) {
if(strcmp(point,".csv") == 0) {
//ends with csv
}
}

EDIT : fixed formatting

Get file extension in lowercase in C

Your code is attempting to change a constant string, "test.PDF", which is not allowed in C. You need to store the string in writable memory and the problem will go away:

char filename[] = "test.PDF"
char *ext = get_filename_ext(filename) ;
// ext now points to memory inside filename, and
// we can write to it

Parse out the file extension from a file-path in C

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

int endswith(const char* haystack, const char* needle)
{
size_t hlen;
size_t nlen;
/* find the length of both arguments -
if needle is longer than haystack, haystack can't end with needle */
hlen = strlen(haystack);
nlen = strlen(needle);
if(nlen > hlen) return 0;

/* see if the end of haystack equals needle */
return (strcmp(&haystack[hlen-nlen], needle)) == 0;
}

int main(int argc, char** argv) {

if(argc != 3) {
printf("Usage: %s <string> <test-ending>\n", argv[0]);
return 1;
}

printf("Does \"%s\" end with \"%s\"? ", argv[1], argv[2]);

if(endswith(argv[1], argv[2])) {
printf("Yes!\n");
} else {
printf("No!\n");
}

return 0;
}


Related Topics



Leave a reply



Submit