用于将文件路径拆分为路径和文件的功能

时间:2009-10-15 21:43:32

标签: c string

假设我有一个功能:

void split_path_file(char** p, char** f, char *pf)
{
    //malloc and set *p to file path, malloc and set *f to file name
    //pf is the pointer to the full file and path "C:\sponge\bob\square.pants"
    // edit: leave pf in its origional state
}

最好的方法是什么?

6 个答案:

答案 0 :(得分:7)

void split_path_file(char** p, char** f, char *pf) {
    char *slash = pf, *next;
    while ((next = strpbrk(slash + 1, "\\/"))) slash = next;
    if (pf != slash) slash++;
    *p = strndup(pf, slash - pf);
    *f = strdup(slash);
}

(如果pf == slash,则没有目录组件。)

答案 1 :(得分:3)

参加聚会可能有点晚了,但我找到并且多年来一直使用的最佳解决方案是两个函数dirnamebasename

path         dirname    basename
"/usr/lib"    "/usr"    "lib"
"/usr/"       "/"       "usr"
"usr"         "."       "usr"
"/"           "/"       "/"

它们非常适合分离路径/文件名的各个部分。与realpath()一起,它们在简单和强大方面是无与伦比的。

http://linux.die.net/man/3/basename

http://man7.org/linux/man-pages/man3/realpath.3.html

答案 2 :(得分:1)

向前翻阅字符串直到你到达第一个'\\'然后将* f设置为它之后的所有内容和* p之前的所有内容和'\\'。

答案 3 :(得分:1)

最简单的方法似乎是从头开始并朝着开始工作,寻找第一个分隔符。然后你有两个案例:要么你找到了一个,要么你没找到。这样的事情应该为你做到:

#include <stdlib.h>
#include <string.h>

void split_path_file(char **p, char **f, char *pf) {
  char *newcopy = malloc(strlen(pf) + 1);
  strcpy(newcopy, pf);

  for (z=newcopy+strlen(newcopy); z>newcopy; z--) {
    if (*z == '/' || *z == '\\')
      break;
  }

  if (z > newcopy) {
    *p = newcopy;
    *z = '\0';
    *f = z+1;
  } else {
    *f = newcopy;
    *p = NULL;
  }
}

更新:@ ephemient的评论下面指出上述方法不会让*p*f适合调用free()。如果这很重要,那么需要更复杂的东西:

#include <stdlib.h>
#include <string.h>

void split_path_file(char **p, char **f, char *pf) {

  /* Find last delimiter. */
  char *z;
  for (z=pf+strlen(pf); z>=pf; z--) {
    if (*z == '/' || *z == '\\')
      break;
  }

  if (z >= pf) {
    /* There is a delimiter: construct separate
       path and filename fragments. */
    printf("--> %i\n", z-pf);
    *p = malloc(z-pf+1);
    strncpy(*p, pf, z-pf);
    (*p)[z-pf] = '\0';
    *f = malloc(strlen(z));
    strcpy(*f, z+1);
  } else {
    /* There is no delimiter: the entire
       string must be a filename. */
    *p = NULL;
    *f = malloc(strlen(pf)+1);
    strcpy(*f, pf);
  }
}

答案 4 :(得分:0)

我想出了以下内容,当然这假设pf是malloced。

void split_path_file(char** p, char **f, char *pf)
{
    char *posp = strrchr(pf, '\\');
    *posp = '\0';
    *p = strdup(pf);
    *f = strdup(posp+1);
    *posp = '\\';
}

不确定这是否比上述答案更好。

答案 5 :(得分:0)

int
stripfilenameandpath (char *path, char *onlypath, char *onlyfilename)
{
/*
documentacao

path = path com path e arquivo
onlypath = somente o path
onlyfilename = somente o arquivo sem o path

*/
    int ret;
    int i;
    int p;
    char temp[255];

    char *fixo;
#ifdef WIN32
    const int separator = '\\';
#else
    const int separator = '/';
#endif

    fixo = path;

    if (path == NULL)
      {

          if (onlypath != NULL)
            {
                memset (onlypath, 0, 1);
            }

          if (onlyfilename != NULL)
            {
                memset (onlyfilename, 0, 1);
            }

          return 1;
      }

    ret = strlen (path);

    if (!ret)
      {

          if (onlypath != NULL)
            {
                memset (onlypath, 0, 1);
            }

          if (onlyfilename != NULL)
            {
                memset (onlyfilename, 0, 1);
            }

          return 0;
      }

    for (i = 0; i  -1; i--)
      {

          if (temp[i] == separator)
            {
                temp[i + 1] = 0;
                break;
            }
          p++;
      }

    p = ret - p;

    fixo += p + 1;

    if (onlypath != NULL)
      {
          strcpy (onlypath, temp);
      }

    if (onlyfilename != NULL)
      {
          strcpy (onlyfilename, fixo);
      }

    return 0;
}