【问题标题】:Scandir Own filter functionScandir 自带过滤功能
【发布时间】:2016-06-22 15:08:41
【问题描述】:

我必须编写 2 个函数,过滤器 - 名称 > 5 个字符,并且我必须按类型对它们进行排序。

过滤函数应该是这样的?

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

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

排序怎么样,在dirent->d_type方面,但是如何排序呢?

【问题讨论】:

  • 只是int filter(const struct dirent *entry)...您将函数指针传递给scandir(),但过滤器函数本身并未声明为指针。
  • return entry 不正确。返回类型是int,所以我假设你应该返回 0 或 1。

标签: c linux scandir


【解决方案1】:

您是否考虑过查看man 3 scandir 页面?

(我发现 Linux man-pages project 手册页是最新的 C 库和系统级编程。)

如果我们有一个函数需要调用者指定一个辅助函数,我们的函数应该调用它来完成某些任务,我们将它声明为一个函数指针。换句话说,scandir() 函数的原型是

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

过滤器和比较函数的原型实际上是

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

功能的愚蠢实现(不满足您的锻炼要求)可能是例如

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);
}

使用POSIX.1-2008写代码的时候记得加

#define _POSIX_C_SOURCE 200809L

在任何#includes 之前。为了使您的代码在不同的环境中正常工作(例如,在我们世界上的任何 Linux 系统中,在文件名中计算 字符 而不是 字节),还有#include <locale.h>,并添加

setlocale(LC_ALL, "");

在您阅读/扫描或写入/打印任何内容之前,请在您的main() 中。 (虽然 可以 做更多的事情来进一步本地化他们的程序,但以上通常就足够了。处理文本文件应该使用宽字符串 (L"This is a ωide §tring liteℛal ?") 和 wchar_t 和 @ 987654335@ 用于字符串和字符的类型,具有宽字符串 I/O 功能。它并不比在愚蠢的 中更复杂或更难做,“27 个 ASCII 字母对每个人来说都足够了,即使它使你的名字在你的母语中变成了一个肮脏的词” 方式。

如果你的老师没有提到这些,你应该问为什么。不能正确处理文件或文本Nöminäl Änimäl needs more €, and cowbell 的程序在当今时代不应该被接受。在学习正确的方法之前,没有必要先学习错误的方法,因为正确的方法和错误的方法一样容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2016-07-15
    • 1970-01-01
    相关资源
    最近更新 更多