问题
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 #include
s. 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