#include <stdio.h>
int mosrcat(char *o, int tsize, ...) {
register int cot = 0;
va_list ap;
va_start(ap, tsize);
char *t = va_arg(ap, char *);
while(t != NULL) {
while((*(o++) = *(t++)) != 0) {
cot++;
if(cot == tsize) {
*(o) = 0;
return cot;
}
}
t = va_arg(ap, char *);
o--;
}
va_end(ap);
return cot;
}
int mofibasename(const char *file_addr, char *fbasename) {
register int mo = mosrlen(file_addr) - 1;
register int n = 1;
if(*(file_addr+mo) == '/') {
printf("F\n");
mo--;
}
while(mo != 0) {
if(*(file_addr+mo) == '/') break;
mo--;
n++;
}
return mosrcat(fbasename, n, file_addr, NULL);
}
int main(void) {
char o[255];
printf("%d:%s\n", mofibasename("/home/Joe/Skh/", o), o);
return 0;
}
这是我的代码。 mofibasename()用于将文件基本名称与完整文件路径分开。
实施例。 /home/Joe/Downloads/x.pdf
- &gt; x.pdf
防爆。 /etc/passwd
- &gt; passwd
但是这个功能并没有奏效。它输出为/home
(输入:/home/Joe/Skh/
)。
我有什么不对吗?我尝试了很多次。
答案 0 :(得分:1)
你可能会过度思考它。如果你只想修改文件名中的路径(不使用string.h
函数),你需要做的就是找到字符串的结尾并向后工作,直到找到/
或者开头,例如
char *trimpath (const char *s)
{
if (!s || !*s) return NULL; /* validate input string */
const char *p = s;
for (; *p; p++); /* find null-terminator */
--p; /* reposition at last char */
for (; p > s; p--) /* find char after '/' */
if (*(p - 1) == '/')
break;
return (char *)p;
}
该函数只返回一个指向文件名开头的指针,其中包含总字符串。一个简短的工作示例,它将/path/filename.ext
组合作为第一个参数(或者如果没有给出参数,则使用自己的默认示例名称):
#include <stdio.h>
char *trimpath (const char *s);
int main (int argc, char **argv) {
const char *path = argc > 1 ? argv[1] : "/some/path/to/a/file.txt";
printf ("\n full path : %s\n filename : %s\n", path, trimpath (path));
return 0;
}
char *trimpath (const char *s)
{
if (!s || !*s) return NULL; /* validate input string */
const char *p = s;
for (; *p; p++); /* find null-terminator */
--p; /* reposition at last char */
for (; p > s; p--) /* find char after '/' */
if (*(p - 1) == '/')
break;
return (char *)p;
}
示例使用/输出
$ ./bin/trimpath
full path : /some/path/to/a/file.txt
filename : file.txt
使用string.h
,您可以将功能缩短为:
char *trimpath (const char *s)
{
if (!s) return NULL;
char *p = strrchr (s, '/');
return p ? p + 1 : s;
}
看看他们两个以及任何其他答案,如果您有任何问题,请告诉我。
答案 1 :(得分:0)
return mosrcat(fbasename, n, file_addr, NULL);
此时n
是1 +基本名称中的字符数。您正在复制n
的开头中的file_addr
个字符。
听起来你要做的就是从n
开始0
,而不是从1
开始,然后从file_addr
开始的最后一个斜线复制:
return mosrcat(fbasename, n, file_addr+mo+1, NULL);
答案 2 :(得分:0)
如果您的操作系统支持POSIX,POSIX会提供完全符合您要求的basename()
function:
命名强>
basename - 返回路径名的最后一个组件
<强>概要强>
[XSI] [Option Start] #include <libgen.h> char *basename(char *path); [Option End]
<强>描述强>
basename()函数应采用path指向的路径名 并返回指向路径名的最后一个组件的指针,删除 任何尾随'/'字符。
...
注意粗体部分 - POSIX basename()
可以修改其参数。
另外,在Linux上使用basename()
时要小心 - Linux提供了两个具有不同语义的两个 basename()
函数。根据{{3}}:
说明
警告:basename()有两个不同的功能 - 见下文。
...
在Linux上使用basename()
之前阅读该手册页。