Scandir Own filter function

徘徊边缘 提交于 2020-01-06 15:25:36

问题


I must write 2 functions, filter - names > 5 chars and I must sort them by types.

Filtr function should look like this ?

int (* filter) (const struct dirent* entry) {

    if ( (strlen(entry>d_name) - 1 ) > 5 ) {
        return entry;
    }
}

How about sort, in dirent its dirent->d_type, but how to sort ?


回答1:


Have you considered taking a look at the man 3 scandir page?

(I find the Linux man-pages project man pages most up-to-date for C library and system level programming.)

If we have a function that needs the caller to specify a helper function our function should call to do some task, we declare it as a function pointer. In other words, while the prototype for the scandir() function is

int scandir(const char *dirp, struct dirent ***namelist,
            int (*filter)(const struct dirent *),
            int (*compar)(const struct dirent **, const struct dirent **));

the prototypes for the filter and comparison functions are actually

int myfilter(const struct dirent *);
int mycompar(const struct dirent **, const struct dirent **);

Silly implementations for the functions (that do not fulfill your exercise requirements) could be for example

int myfilter(const struct dirent *entry)
{
    /* man 3 scandir says "entries for which filter()
     * returns nonzero are stored".
     *
     * Since file names in Linux are multibyte strings,
     * we use mbstowcs() to find out the length
     * of the filename in characters.
     *
     * Note: strlen() tells the filename length in bytes,
     *       not characters!
    */
    const size_t len = mbstowcs(NULL, entry->d_name, 0);

    /* Keep filenames that are 3 or 7 characters long. */
    return (len == 3) || (len == 7);
}

int mycompar(const struct dirent **entry1, const struct dirent **entry2)
{
    const size_t len1 = mbstowcs(NULL, (*entry1)->d_name, 0);
    const size_t len2 = mbstowcs(NULL, (*entry2)->d_name, 0);

    /* Compare by file name lengths (in characters),
     * sorting shortest file names first. */
    return (int)((ssize_t)len1 - (ssize_t)len2);
}

When writing code using POSIX.1-2008, remember to add

#define _POSIX_C_SOURCE 200809L

before any #includes. To make your code work correctly in different environments (for example, counting characters instead of bytes in file names, in any Linux system around our world), also #include <locale.h>, and add

setlocale(LC_ALL, "");

in your main() before you read/scan or write/print anything. (Although there is lots more one can do to localize their programs even further, the above very often suffices. Processing text files should be done using wide strings (L"This is a ωide §tring liteℛal 😃") and the wchar_t and wint_t types for strings and characters, with the wide string I/O functions. It isn't any more complex or hard to do right, than doing it in the idiotic "The twenty-seven ASCII letters are sufficient for everyone, even if it makes your name into a dirty word in your native language" way.

If your teacher does not mention these, you should ask why. A program that cannot handle files or text Nöminäl Änimäl needs more €, and cowbell, correctly, should not be acceptable in this day and age. There is no need to first learn a wrong way to do things before learning the right way, because the right way is just as easy as the wrong way is.



来源:https://stackoverflow.com/questions/37971949/scandir-own-filter-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!