Versuchen:
char *remove(char* mystr) {
char *retstr;
char *lastdot;
if (mystr == NULL)
return NULL;
if ((retstr = malloc (strlen (mystr) + 1)) == NULL)
return NULL;
strcpy (retstr, mystr);
lastdot = strrchr (retstr, '.');
if (lastdot != NULL)
*lastdot = '\0';
return retstr;
}
Sie werden zurückgegebenen String selbst befreien müssen. Es findet einfach die letzte .
in der Zeichenfolge und ersetzt sie durch ein Nullabschlusszeichen. Es behandelt Fehler (NULL übergeben oder nicht genügend Arbeitsspeicher), indem NULL zurückgibt.
Es wird nicht mit Dingen wie /this.path/is_bad
arbeiten, da es die .
in der Nicht-Dateiteil zu finden, aber man könnte damit umgehen, indem auch ist, es ist Position ein strrchr
von /
, oder was auch immer Ihr Pfadseparator ist, und gewährleistet dabei NULL oder vor der .
Position.
Eine Allzweck-Lösung könnte für dieses Problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// remove_ext: removes the "extension" from a file spec.
// mystr is the string to process.
// dot is the extension separator.
// sep 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 dot, char sep) {
char *retstr, *lastdot, *lastsep;
// 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);
lastdot = strrchr (retstr, dot);
lastsep = (sep == 0) ? NULL : strrchr (retstr, sep);
// If it has an extension separator.
if (lastdot != NULL) {
// and it's before the extenstion separator.
if (lastsep != NULL) {
if (lastsep < lastdot) {
// then remove it.
*lastdot = '\0';
}
} else {
// Has extension separator with no path separator.
*lastdot = '\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;
}
und dies erzeugt:
[hello]
[hello]
[hello]
[hello.txt]
[/no.dot/in_path]
[/has.dot/in]
[/no]
Ist C++ in Ordnung? –
Sie wissen, dass "Dateiendung" und "letzte drei Zeichen eines Dateinamens" ** nicht ** das gleiche sind? Einige Dateien haben mehr oder weniger als 3 Zeichen in ihrem Extenson: 'Foo.java',' foo.c' sind gute Beispiele. Einige haben sogar mehrere Punkte in der Erweiterung (en): 'foo.tar.gz'. Und wieder andere werden einen Punkt außerhalb der Erweiterung haben: 'foo.bar.txt'. Kurz gesagt: Es ist eine nicht-triviale Aufgabe. –
Welche Plattform? Es ist nicht trivial, dies in C korrekt zu tun, und in den Standardbibliotheken ist nichts enthalten (weil Dateinamen plattformspezifisch sind). Zum Beispiel ist ein Backslash ein Pfadtrennzeichen in Windows, aber nicht in * nix, so dass für 'some \ path.to \ file' das Ergebnis des" Entfernens der Erweiterung "unter Windows' some \ path.to \ file' lautet (weil Es gibt keine Erweiterung, aber on * nix ist 'some \ path' (weil die Erweiterung' to \ file' ist). –