C中的切割路径

时间:2012-04-30 03:22:50

标签: c string filepath

我想在前言中说我在C中做了很少的编程,所以我更愿意知道给定解决方案的原因而不仅仅是它的原理。

我正在尝试编写一个将采用路径名的函数,并将路径名返回到同一目录中的不同文件。

  "/example/directory/with/image.png" => "/example/directory/with/thumbnail.png"

在阅读realpathdirname的示例用法之后我尝试了什么(我在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;
}

给了我一个段错误。任何提示?

2 个答案:

答案 0 :(得分:2)

我看到的唯一问题是chop_path例程的签名;它应该是

char *chop_path(char *orig) {

您的版本缺少*。这实际上有很大的不同;没有*,你有效地告诉dirnamerealpath将参数字符串中第一个字符的字符代码解释为路径的数字地址(即指针) 。这将指向一个你绝对没有分配的内存不足的位置;尝试使用它会导致“分段错误”错误,这有效地意味着您正试图触摸您不允许的内存。

另一个问题是dirname()函数是在libgen.h中声明的,你没有包含它。如果不包含该头,则编译器假定dirname()返回int而不是指针,而在64位体系结构中,函数的64位返回值被切换为32位,一个错误的指针被分配给dname,这将导致你的seg错误。

答案 1 :(得分:1)

如果您不想使用dirnamerealpath,不需要的字符串缓冲区和字符串操作等,您可以执行以下操作:

#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 
$