6

How does one pass a const char *path to fts_open? I would like to pass a filePath.

some_id
  • 29,466
  • 62
  • 182
  • 304
  • 1
    I think this thread has an nice example as the accepted answer http://stackoverflow.com/questions/983376/recursive-folder-scanning-in-c – Mikhail Mar 28 '12 at 20:48

3 Answers3

3

I assume you want to know how to pass this single path to the argv (type char const **) parameter of fts_open. This parameter is described thus:

argv

Is a NULL terminated array of character pointers naming one or more paths that make up the file hierarchy.

So you need to create an array of length two whose elements are of type char*. Put your path in the first element and put NULL in the second element. Like this:

char const *argv[] = { path, NULL };

You can now pass argv to fts_open.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 4
    Still, fts_open only takes `char *const *` instead of `const char *const *` :-/ – jørgensen Mar 28 '12 at 20:55
  • You can pass non-const pointers to a function that accepts const pointers. In const correctness, the function signature is telling you that the function is not going to modify the data pointed to by the argument. In this case, `fts_open` isn't going to modify the contents of `argv`, or the values its elements point to. – tomlogic Mar 28 '12 at 21:00
  • But I was being a bit sloppy in my original version. I've added the appropriate `const` qualifiers now. That said, I suspect the presence of `const` just makes it harder for Helium3 to understand the double indirection. For the sake of exposition, sometimes it can be better to focus on one issue at a time. – David Heffernan Mar 28 '12 at 21:02
  • 1
    This *does not work*. `fts_open` expects a (const) pointer to `char*`, not to `char const*`. – Konrad Rudolph Jan 22 '21 at 12:00
2

fts_open expects an array of char* to be compatible with the main function’s argv array (and since char** can’t be converted to char const**).

So you need to create such an array. In particular, if you have a path in a char const* variable, you must copy the string; e.g.:

char path_copy[PATH_MAX];
strcpy(path_copy, path);
char *argv[] = {path_copy, NULL};
FTS *fts = fts_open(argv, FTS_PHYSICAL, nullptr);

This is using a statically-sized buffer. Depending on your requirements you may want to dynamically allocate a buffer of appropriate size instead.

… it may be possible (likely, even) that fts_open doesn’t actually modify its arguments, so casting away the const instead of copying the string should be possible. But the documentation of fts_open gives no such guarantee, so I advise against it.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
0

The first argument to fts_open() is, "a NULL terminated array of character pointers naming one or more paths that make up the file hierarchy."

So, you could pass it like this:

char *pathlist[2];

pathlist[0] = filePath;
pathlist[1] = NULL;

fts_open( pathlist, ...);
tomlogic
  • 11,489
  • 3
  • 33
  • 59
  • This doesn’t work if the type of `filePath` is `char const*`. – Konrad Rudolph Jan 22 '21 at 12:01
  • That's correct. The function prototype for `fts_open()` expects a `char * const *path_argv` as the first parameter. Per cdecl.org, this is a `pointer to const pointer to char`, and you cannot pass a `pointer to a const pointer to const char`. Is there another way to write this to pass `const char *pathlist[]` to `fts_open()` without casting away a `const`? – tomlogic Jan 23 '21 at 17:55
  • The only two ways I’m aware of are (a) cast away const-ness, which might be undefined here (the documentation of `fts_open` does not guarantee that it will work!), or (b) copying — see my answer. – Konrad Rudolph Jan 23 '21 at 19:16