我想在前言中说我在C中做了很少的编程,所以我更愿意知道给定解决方案的原因而不仅仅是它的原理。
我正在尝试编写一个将采用路径名的函数,并将路径名返回到同一目录中的不同文件。
"/example/directory/with/image.png" => "/example/directory/with/thumbnail.png"
在阅读realpath
和dirname
的示例用法之后我尝试了什么(我在Linux上工作;如果有跨平台的等价物,请告诉我)是:
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *chop_path(char *orig) {
char buf[PATH_MAX + 1];
char *res, *dname, *thumb;
res = realpath(orig, buf);
if (res) {
dname = dirname(res);
thumb = strcat(dname, "/thumbnail.png");
return thumb;
}
return 0;
}
编译它似乎工作,但用
运行程序int main(void) {
char *res = chop_path("original.png");
if (res) {
printf("Resulting pathname: %s", res);
}
return 0;
}
给了我一个段错误。任何提示?
答案 0 :(得分:2)
我看到的唯一问题是chop_path
例程的签名;它应该是
char *chop_path(char *orig) {
您的版本缺少*
。这实际上有很大的不同;没有*
,你有效地告诉dirname
和realpath
将参数字符串中第一个字符的字符代码解释为路径的数字地址(即指针) 。这将指向一个你绝对没有分配的内存不足的位置;尝试使用它会导致“分段错误”错误,这有效地意味着您正试图触摸您不允许的内存。
另一个问题是dirname()
函数是在libgen.h
中声明的,你没有包含它。如果不包含该头,则编译器假定dirname()
返回int
而不是指针,而在64位体系结构中,函数的64位返回值被切换为32位,一个错误的指针被分配给dname
,这将导致你的seg错误。
答案 1 :(得分:1)
如果您不想使用dirname
,realpath
,不需要的字符串缓冲区和字符串操作等,您可以执行以下操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define FILE_MAX 100
void chop_path(char path_name[], char new_file[]) {
int len = strlen(path_name);
int i;
for (i=len-1; i>0 ; i--) {
if (path_name[i] == '/') {
strcpy(path_name+i+1, new_file);
break;
}
}
return;
}
int main(void) {
char path[PATH_MAX + 1] = "/this/is/a/path/filename.c";
char new_file[FILE_MAX] = "newfilename.txt";
printf("old : %s \n", path);
chop_path(path, new_file);
printf("new : %s \n", path);
return 0;
}
输出:
$ gcc path.c
$ ./a.out
old : /this/is/a/path/filename.c
new : /this/is/a/path/newfilename.txt
$