4

I have an array of strings in C. These strings store the paths of filesystems that need to be unmounted.

For example...
mountlist[0] = "/proc"
mountlist[1] = "/dev"
mountlist[2] = "/dev/shm"
and so on...

I need to unmount the nested filesystems before the filesystems they are mounted over (so /dev/shm needs to be unmounted before /dev). I was thinking that the easiest way to do this would be to sort the strings by length, longest first. I have the number of strings in the array stored in the integer i.

With the code that I've been able to come up with so far, given that strnum is an integer of the string I need to access, the strings are accessible with mountlist[strnum] and the corresponding length is stored in length[strnum].

In conclusion, how can I sort the strings in array by greatest to least length? I don't need to actually sort the strings, I just need to access them in the right order. I can't figure out how to write it, but I was thinking of code that creates an int array with the number of each string array in the right order (the example above would be {2, 0, 1}), so if that array was named sort then mountlist[sort[0]] would be the longest string. With such an array, the corresponding for loop would be:

for (int q = 0; q < i; q++) {
    umount(mountlist[sort[q]]);
}
16
  • 2
    do you know about qsort()? Commented Aug 29, 2018 at 13:53
  • @Fureeish No, I'll look it up. Commented Aug 29, 2018 at 13:59
  • If the order is based on the length it may fail. Example: if you have "/dev/shm" and "/somenonnested", latter will be unmounted before "/dev/shm" because it's length is longer... Commented Aug 29, 2018 at 14:00
  • Duplicate of stackoverflow.com/a/27003340/4288486 ? Commented Aug 29, 2018 at 14:05
  • 2
    "/path" will always be lexicographically less than "/path/contained" where /path is a directory, and contained is something in that directory. So it is not necessary to sort by string length - sorting in reverse-lexicographical order will be sufficient Commented Aug 29, 2018 at 14:24

2 Answers 2

3

You can just use qsort with a custom comparator:

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

int cmp(const void *first, const void *second) { 
    const char **firstCast = (const char ** )first;
    const char **secondCast = (const char **) second;
    return strcmp(*secondCast, *firstCast);
}
int main(void) {
    const char *a[3];
    a[0] = "longest";
    a[1] = "short";
    a[2] = "medium";
    qsort(a, 3, sizeof(char *), cmp);
    for (int i = 0 ; i < 3; i++) {
        printf("%s\n", a[i]);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

He wants the sorting based on string lengths (which may not be the right choice btw, see my comment to the question), not based on string comparision.
1

If you don't want to depend on anything "external" like qsort, which may or not be available in your environment, this should do it:

for (int j = 0; j < i; ++j) sort[j] = j;

for (int j = 0; j < i - 1; ++j) {
    int longest = j;
    for (int k = j + 1; k < i; ++k) {
        if (length[sort[k]] > length[sort[longest]]) longest = k;
    }
    int tmp = sort[longest];
    sort[longest] = sort[j];
    sort[j] = tmp;
}

1 Comment

qsort is included in the C standard so there is no question about it being available.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.