如何在C中编写* nix的基本名称

时间:2012-05-16 06:44:58

标签: c substring

我想从字符串中提取基本名称,例如

/opt/home/etc/sample

也就是说,我想解析返回sample或子字符串的大字符串 在最后一个/字符之后。字符串可以是任意长度。

怎么可以这样做?

3 个答案:

答案 0 :(得分:5)

char *input = "/opt/home/etc/sample";
char *output = NULL;

output = strrchr(input, '/');

if(output != NULL)
{
    printf("%s\n", output);
}

或者其他方面是您可以尝试自己解析它(下面的代码只是一个示例,不能处理所有错误和边界条件,您可以自己尝试和学习)

char *input = "/opt/home/etc/sample";
int len = 0;
char *temp = NULL;

len = strlen(input);
temp = input + (len-1);
len--;

while((*temp != '/') && (len >= 0))
{
  temp--;
  len--;
}


if(len>=0)
{
   printf("%s\n", temp);
}

答案 1 :(得分:0)

您可以使用strtok_r

#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This/a/sample/string";
  char * pch;
  char * ans;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok_r (str,"/");
  if(pch==NULL)
  ans = str;
  while (pch != NULL)
  {
    ans = pch;
    pch = strtok_r (NULL, "/");
  }
  return 0;
}

请注意代码中的一些小错误

答案 2 :(得分:0)

POSIX中有basename / dirname个函数。它们的返回值将指向静态内存或输入的某些后缀,因此不需要释放它。这可能比自己分割字符串更容易:

  // assuming you own *path:
  char *file = basename(path);
  char *dir = dirname(path);   //that's all!

path".""..""foo/"(然后,basename为"." - 正确的事情)时,他们还会处理特殊情况。< / p>

但要注意,如果你不拥有字符串:它们采用非const参数,并且可以修改它。

如果您确实需要在basename上使用const char *,解决方案大致相同

  #include <libgen.h>  // POSIX

  void die(const char * errormessage);

  /* version of basename(3) that does not modify its argument.
   * This assumes that "path" is correctly 0-terminated!
   * Please free() the return value after use. */
  char * basename_safe(const char * path)
  {
    char * result;
    char * what_basename_says;

    if (!path) {
      // return a pointer to ".":
      result = malloc(2 * sizeof(char));
      if (!result) die("malloc failed!");
      result[0] = '.';
      result[1] = 0;
      return result;
    }

    // in case path is the empty string, we need 2 chars to store the result ".",
    // so add 2:
    result = malloc((2 + strlen(path)) * sizeof(char));
    if (!result) die("malloc failed");

    // basename wants write access to its argument:
    strcpy(result, path);

    what_basename_says = basename(result);
    // now what_basename_says actually may be a pointer into *result.

    strcpy(result, what_basename_says);
    // to allow for free(result)

    return result;
  }

但是,正如我之前所说:如果您知道可以修改*path,那么您也可以使用basename而不用这一切。