Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to remove extension from file name?

I want to throw the last three character from file name and get the rest?

I have this code:

char* remove(char* mystr) {

    char tmp[] = {0};
    unsigned int x;

    for (x = 0; x < (strlen(mystr) - 3); x++)
        tmp[x] = mystr[x];

    return tmp;
}
like image 758
alaamh Avatar asked Apr 29 '10 11:04

alaamh


People also ask

How do I remove extensions in Windows 10?

To remove any extension, choose one of the following methods: In Microsoft Edge, select and hold (or, right-click) the icon of the extension you want to remove (to the right of your browser address bar). Select Remove from Microsoft Edge > Remove.

How do I disassociate a file extension?

bat Now right click any file you want to disassociate and choose 'Open with' - 'Choose another app' -' More Apps' Check the box marked 'Always use this app' Scroll to the bottom and click 'Look for another app on this PC' Navigate to the XXX. bat on your Desktop and select that Finally delete XXX.

How do I remove all file extensions in Windows?

You can do this using the Windows GUI. Enter "*. wlx" in the search box in explorer. Then after the files have been found, select them all (CTRL-A) and then delete using the delete key or context menu.


4 Answers

Try:

char *remove(char* myStr) {
    char *retStr;
    char *lastExt;
    if (myStr == NULL) return NULL;
    if ((retStr = malloc (strlen (myStr) + 1)) == NULL) return NULL;
    strcpy (retStr, myStr);
    lastExt = strrchr (retStr, '.');
    if (lastExt != NULL)
        *lastExt = '\0';
    return retStr;
}

You'll have to free the returned string yourself. It simply finds the last . in the string and replaces it with a null terminator character. It will handle errors (passing NULL or running out of memory) by returning NULL.

It won't work with things like /this.path/is_bad since it will find the . in the non-file portion but you could handle this by also doing a strrchr of /, or whatever your path separator is, and ensuring it's position is NULL or before the . position.


A more general purpose solution to this problem could be:

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

// remove_ext: removes the "extension" from a file spec.
//   myStr is the string to process.
//   extSep is the extension separator.
//   pathSep is the path separator (0 means to ignore).
// Returns an allocated string identical to the original but
//   with the extension removed. It must be freed when you're
//   finished with it.
// If you pass in NULL or the new string can't be allocated,
//   it returns NULL.

char *remove_ext (char* myStr, char extSep, char pathSep) {
    char *retStr, *lastExt, *lastPath;

    // Error checks and allocate string.

    if (myStr == NULL) return NULL;
    if ((retStr = malloc (strlen (myStr) + 1)) == NULL) return NULL;

    // Make a copy and find the relevant characters.

    strcpy (retStr, myStr);
    lastExt = strrchr (retStr, extSep);
    lastPath = (pathSep == 0) ? NULL : strrchr (retStr, pathSep);

    // If it has an extension separator.

    if (lastExt != NULL) {
        // and it's to the right of the path separator.

        if (lastPath != NULL) {
            if (lastPath < lastExt) {
                // then remove it.

                *lastExt = '\0';
            }
        } else {
            // Has extension separator with no path separator.

            *lastExt = '\0';
        }
    }

    // Return the modified string.

    return retStr;
}

int main (int c, char *v[]) {
    char *s;
    printf ("[%s]\n", (s = remove_ext ("hello", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("hello.", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("hello.txt", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("hello.txt.txt", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("/no.dot/in_path", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("/has.dot/in.path", '.', '/'))); free (s);
    printf ("[%s]\n", (s = remove_ext ("/no.dot/in_path", '.', 0))); free (s);

    return 0;
}

and this produces:

[hello]
[hello]
[hello]
[hello.txt]
[/no.dot/in_path]
[/has.dot/in]
[/no]
like image 171
paxdiablo Avatar answered Nov 09 '22 23:11

paxdiablo


Use rindex to locate the "." character. If the string is writable, you can replace it with the string terminator char ('\0') and you're done.

char * rindex(const char *s, int c);

 DESCRIPTION
 The rindex() function locates the last character matching c (converted to a char) in the null-terminated string s.
like image 43
diciu Avatar answered Nov 10 '22 00:11

diciu


If you literally just want to remove the last three characters, because you somehow know that your filename has an extension exactly three chars long (and you want to keep the dot):

char *remove_three(const char *filename) {
    size_t len = strlen(filename);
    char *newfilename = malloc(len-2);
    if (!newfilename) /* handle error */;
    memcpy(newfilename, filename, len-3);
    newfilename[len - 3] = 0;
    return newfilename;
}

Or let the caller provide the destination buffer (which they must ensure is long enough):

char *remove_three(char *dst, const char *filename) {
    size_t len = strlen(filename);
    memcpy(dst, filename, len-3);
    dst[len - 3] = 0;
    return dst;
}

If you want to generically remove a file extension, that's harder, and should normally use whatever filename-handling routines your platform provides (basename on POSIX, _wsplitpath_s on Windows) if there's any chance that you're dealing with a path rather than just the final part of the filename:

/* warning: may modify filename. To avoid this, take a copy first
   dst may need to be longer than filename, for example currently
   "file.txt" -> "./file.txt". For this reason it would be safer to
   pass in a length with dst, and/or allow dst to be NULL in which
   case return the length required */
void remove_extn(char *dst, char *filename) {
    strcpy(dst, dirname(filename));
    size_t len = strlen(dst);

    dst[len] = '/';
    dst += len+1;

    strcpy(dst, basename(filename));
    char *dot = strrchr(dst, '.');
    /* retain the '.' To remove it do dot[0] = 0 */
    if (dot) dot[1] = 0;
}

Come to think of it, you might want to pass dst+1 rather than dst to strrchr, since a filename starting with a dot maybe shouldn't be truncated to just ".". Depends what it's for.

like image 23
Steve Jessop Avatar answered Nov 10 '22 01:11

Steve Jessop


I would try the following algorithm:

last_dot = -1

for each char in str:
    if char = '.':
        last_dot = index(char)

if last_dot != -1:
    str[last_dot] = '\0'
like image 42
Bastien Léonard Avatar answered Nov 09 '22 23:11

Bastien Léonard