0

I'm trying to perform DFS on a folder that can contain sub folders. The goal is to locate all .txt files from a directory. I need to find the .txt files in the order that DFS finds them and preserve the order of files in a folder.

Currently my code for scanning a directory uses the scandir() function:

int n = scandir(path, &namelist, NULL, alphasort);

This sorts the files in a folder in alphabetical order, which isn't exactly what I want.

Edit: I've tried using opendir() and readdir() but this is accessing files in a seemingly random order.

Ryan Marr
  • 83
  • 7
  • Are you programming on Linux? – Roberto Caboni Apr 16 '20 at 21:40
  • If you don't want to sort the files, `scandir()` is probably the wrong tool for the job. What's wrong with just using `opendir()`, `readdir()`, `closedir()`? – Jonathan Leffler Apr 16 '20 at 21:41
  • 1
    To use `versionsort` a `#define _GNU_SOURCE` is needed before the `#include ` – kaylum Apr 16 '20 at 21:45
  • You say "preserve the order of files in a folder" and yet you discuss different ways of sorting the names of the files in the folder. That's puzzling — which do you want? Sorted order or 'physical order' in some way? If you want sorted order, then `scandir()` is a good choice. If you want 'physical order', it is the wrong choice. What are you seeking really? You also mention DFS — depth-first search. Should you be looking at `nftw()` for the '(new) file tree walk'? Please clarify your requirements by editing some extra information into the question. – Jonathan Leffler Apr 16 '20 at 22:21
  • I apologize for being unclear about this. What I meant to do is iterate through the folder in the order that the files appear. I don't know how to describe this order. I also used opendir() and readdir() but this still accessed the files out of order. Specifically I have folders F1, F2, ... , F10 but it accessed them in the order F4,F1,F5,F10,F,F8,F9,F2,F3,F7 – Ryan Marr Apr 17 '20 at 00:20
  • I believe DFS actually has configurable ordering and some of the available ordering algorithms are somewhat complex. – David Schwartz Apr 17 '20 at 00:43
  • @RyanMarr did my answer solve your issue about `versionsort` symbol resolution? – Roberto Caboni Apr 17 '20 at 17:05
  • Please note, @RyanMarr, that I explicitly requested you to edit the extra information into the question. That's where it belongs. You can format it. What do you mean by "the order that the files appear"? In the output from `ls`? In the output from `*`? When you read the names using `readdir()`? In your GUI file manager? – Jonathan Leffler Apr 18 '20 at 01:09

1 Answers1

0

According to versionsort man page

int versionsort(const void *a, const void *b);

can be passed as a callback to scandir() and is declared in dirent.h.


First thing to check: "Feature Test Macro Requirements"

From the same page linked above:

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

scandir(), alphasort(): _BSD_SOURCE || _SVID_SOURCE

versionsort(): _GNU_SOURCE.

These macros need to be defined before dirent.h inclusion in order to enable the specific feature.


Second thing to check: glibc version

From the same page linked above:

Versions

versionsort() was added to glibc in version 2.1.

Please refer to this question to learn how to check your glibc version.

Community
  • 1
  • 1
Roberto Caboni
  • 7,252
  • 10
  • 25
  • 39
  • This is good advice for how to get `versionsort()` declared and so on, but the question also says "preserve the order of files in a folder". Using either `alphasort()` or `versionsort()` inherently defeats this — the objective must be 'no sort'. And it is not clear how you can achieve 'no sort'. It might be feasible to compare the two pointers (as numbers via `uintptr_t`) and guess that the ones earlier in the directory appear before those that come later, but it is anything but certain. The requirements on `scandir()` that all the allocated memory is freed by `free(namelist)` are severe. – Jonathan Leffler Apr 16 '20 at 22:00
  • @JonathanLeffler I interpreted the question like `versionsort()` was actually what they were looking for. From [here](https://www.systutorials.com/docs/linux/man/3-versionsort/): _" [versionsort()] [...] sorts directory entries using strverscmp(3) on the strings (*a)->d_name and (*b)->d_name."_ so that, for example _"jan1 < jan10"_ . Isn't that the typical order of presentation of files? Probably you are right and I should have waited for further clarifications from OP. – Roberto Caboni Apr 16 '20 at 22:16