将char *转换为char * const *

时间:2011-11-10 02:33:43

标签: c linux pointers

请原谅这个问题的基本“问题”。我有时会迷上指针。我有char *但我需要将其转换为char * const *才能在fts()函数中正确使用它。我该怎么做?

由于

3 个答案:

答案 0 :(得分:11)

您不应该进行这种转换,因为类型不兼容。

关于指针的指针和指针

char *是指向字符串的指针,而char **是指向字符串的指针。 (const是奖金)。这可能意味着您应该提供一个字符串数组,而不是提供一串字符。

这两件事显然是不相容的。不要将它们与演员混在一起。

关于fts_ * API

要找到问题的解决方案,我们需要阅读fts_ *函数API(例如,在 http://linux.die.net/man/3/fts),我看到了:

FTS *fts_open(char * const *path_argv, int options,
          int (*compar)(const FTSENT **, const FTSENT **));

使用您的char * const *参数path_argv,说明解释为:

  

[...]如果compar()参数为NULL,则目录遍历顺序为path_argv中为根路径列出的顺序[...]

确认fts_open函数确实是一个路径集合,而不是唯一的路径。

所以我猜你需要传递给它的东西如下:

char *p[] = { "/my/path", "/my/other/path", "/another/path", NULL } ;

关于const

C和C ++中的类型从右到左阅读。所以如果你有:

  • char *:指向char的指针
  • char const *:指向const char的指针(即你不能修改指向的字符串,但你可以修改指针)
  • const char *:与char const *
  • 相同
  • char * const:const指向char的指针(即你可以修改指向的字符串,但不能修改指针)
  • char **:指向char的指针
  • char * const *:指向char的const指针(即你可以修改指针,你可以修改char的字符串,但你不能修改中间指针

这可能令人困惑,但是一旦你对指针更熟悉,那么从右到左的顺序阅读它们就会很清楚(如果你用C或C ++编程,你想要成为熟悉指针)。

如果我们回到最初的例子(用C99在gcc上发送一堆警告):

char ** p = { "/my/path", "/my/other/path", "/another/path", NULL } ;

我使用了API,你可以通过两种方式提供你的路径:

    char * p0 = "/my/path" ;
    char * p1 = "/my/other/path" ;
    char * p2 = "/another/path" ;

    /* with a fixed-size array */
    char * pp[] = {p0, p1, p2, NULL} ;

    FTS * fts_result = fts_open(pp, 0, NULL);
  

编辑2011-11-10: snogglethorpe正确评论此解决方案不是C89有效解决方案,即使它与gcc成功编译(不包括pendantic + C89标志)。有关该

的更多信息,请参阅Error: initializer element is not computable at load time

或:

    /* with a malloc-ed array */
    char ** pp = malloc(4 * sizeof(char *)) ;
    pp[0] = p0 ;
    pp[1] = p1 ;
    pp[2] = p2 ;
    pp[3] = NULL ;

    FTS * fts_result2 = fts_open(pp, 0, NULL);
    free(pp) ;

修改

在阅读其他答案后,其中只有两个(mkbmoshbear)避免“只是转换数据”错误。

在我自己的回答中,我忘记了数组的NULL终止符(但后来我不知道Linux API,也不知道fts_ *类的函数,所以...)

答案 1 :(得分:2)

你需要创建第二个数组NULL - 终止(因为fts()的第一个参数是argv)。

E.g。

char *const buf2[2] = { buf, NULL };
fts(buf2);

答案 2 :(得分:2)

我假设你在谈论fts_open

FTS *fts_open(char * const *path_argv, int options,
                 int (*compar)(const FTSENT **, const FTSENT **));

它需要你的是const char*指针的数组,即。一串字符串。 const只是告诉您它不会修改您的字符串,并且您有机会传递const字符串。

const变量可以视为const,但是您通常不应该以相反的方式对待它们。

第一个参数就像传递给argv的{​​{1}}一样,你可能只有:

main

最后一个元素 char *path_argv[] = { "/first_path/", "/second_path/", NULL }; 非常重要,以表明数组的结束。

另请注意,NULL也可以声明为

path_argv

OR *

char **path_argv

其中任何一种都是作为char * const *path_argv 的第一个参数传递的合适类型。但是,您显然必须以与上述不同的方式初始化它,但这些是您可以声明 fts_open的其他方式。我以前做不清楚。

然后只有path_argv,其中fts_open(path_argv, options, compar)是您的选项,而options是您的比较功能。