Hãy thử:
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;
}
Bạn sẽ phải giải phóng chuỗi trả lại cho mình. Nó chỉ đơn giản là tìm thấy .
cuối cùng trong chuỗi và thay thế nó bằng một ký tự terminator null. Nó sẽ xử lý các lỗi (đi qua NULL hoặc hết bộ nhớ) bằng cách trả về NULL.
Nó sẽ không làm việc với những thứ như /this.path/is_bad
vì nó sẽ tìm ra .
trong phần phi-file nhưng bạn có thể xử lý này bằng cách cũng làm một strrchr
của /
, hoặc bất cứ điều gì tách con đường của bạn, và đảm bảo vị trí của nó là NULL hoặc trước vị trí .
.
Một giải pháp mục đích tổng quát hơn cho vấn đề này có thể là:
#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;
}
và điều này tạo ra:
[hello]
[hello]
[hello]
[hello.txt]
[/no.dot/in_path]
[/has.dot/in]
[/no]
Có phải C++ không? –
Bạn biết rằng "phần mở rộng tệp" và "ba ký tự cuối cùng của tên tệp" là ** không ** cùng một điều? Một số tệp có nhiều hơn hoặc ít hơn 3 ký tự trong extenson của chúng: 'Foo.java',' foo.c' là các ví dụ hay. Một số thậm chí có nhiều dấu chấm trong (các) tiện ích mở rộng: 'foo.tar.gz'. Và những người khác sẽ có dấu chấm bên ngoài phần mở rộng: 'foo.bar.txt'. Tóm lại: đó là một nhiệm vụ không tầm thường. –
Nền tảng nào? Nó không phải là tầm thường để làm điều này một cách chính xác trong C, và không có gì trong thư viện chuẩn (vì tên tập tin là một nền tảng bit cụ thể). Ví dụ, dấu gạch chéo ngược là một dấu phân cách đường dẫn trong Windows nhưng không phải trong * nix, do đó, đối với 'some \ path.to \ file', kết quả của" remove the extension "trên Windows là' some \ path.to \ file' (vì không có phần mở rộng), nhưng trên * nix là 'some \ path' (vì phần mở rộng là' to \ file'). –