3

I am trying to use scandir to print a list of files in the current directory. When I try to compile, I am receiving the following errors and warnings:

warning: implicit declaration of function ‘scandir’ [-Wimplicit-function-declaration]
error: ‘alphasort’ undeclared (first use in this function)
note: each undeclared identifier is reported only once for each function it appears in

I am including <dirent.h>, which to my knowledge should define scandir() and all related functions. And I don't see any errors in my code:

#include <dirent.h>
...
int printFiles(){
    struct dirent **nameList;
    int numOfFiles = scandir(".", &nameList, 0, alphasort);

    //TODO print file names
    return numOfFiles;
}
....

I am running Ubuntu 12.04, and I'm compiling using gcc with the -c99 flag.

Am I simply overlooking something? I can't figure out why it's failing to compile.

4

3 回答 3

4

如果使用-std=c99,则头文件仅包含严格属于 C99 标准一部分的函数。scandir()不在 C99 标准中。因此,您必须设置一个预处理器变量以确保包含函数原型。例如,手册页scandir()表明在您执行该操作之前设置_BSD_SOURCE_SVID_SOURCE预处理器变量#include将解决问题。或者,您可以使用#define _GNU_SOURCEwhich 反过来为您设置很多不同的变量(包括_BSD_SOURCE_SVID_SOURCE)。

您的代码仍会在出现警告的情况下编译并正常工作,因为 C 允许您使用隐式定义的函数进行编译,并且链接器会将调用正确链接scandir()到正确的函数。

于 2013-10-18T01:28:31.980 回答
1

您使用的宏由您自己计算机上的 dirent.h 中的宏决定。通常它位于 /usr/include/dirent.h。

  1. 在dirent.h中找到scandir,你会找到使scandir不可见的宏。例如在我的计算机中,它是“__USE_BSD,__USE_MISC”。

    #if defined __USE_BSD || defined __USE_MISC
    /* Return the file descriptor used by DIRP.  */
    extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
    
    # if defined __OPTIMIZE__ && defined _DIR_dirfd
    #  define dirfd(dirp)   _DIR_dirfd (dirp)
    # endif
    
    # ifndef MAXNAMLEN
    /* Get the definitions of the POSIX.1 limits.  */
    #  include <bits/posix1_lim.h>
    
    /* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'.  */
    #  ifdef NAME_MAX
    #   define MAXNAMLEN    NAME_MAX
    #  else
    #   define MAXNAMLEN    255
    #  endif
    # endif
    
    # define __need_size_t
    # include <stddef.h>
    
    # ifndef __USE_FILE_OFFSET64
    extern int scandir (__const char *__restrict __dir,
        struct dirent ***__restrict __namelist,
        int (*__selector) (__const struct dirent *),
        int (*__cmp) (__const void *, __const void *))
    __nonnull ((1, 2));
    # else
    #  ifdef __REDIRECT
    extern int __REDIRECT (scandir,
        (__const char *__restrict __dir,
        struct dirent ***__restrict __namelist,
        int (*__selector) (__const struct dirent *),
        int (*__cmp) (__const void *, __const void *)),
        scandir64) __nonnull ((1, 2));
    #  else
    #  define scandir scandir64
    #  endif
    # endif
    

    你知道现在该怎么做吗?别担心!这不是直接#define 这个宏的好方法。

  2. 打开文件 features.h(位于 /usr/include/features.h),在里面搜索“__USE_MISC”,你可以看到下面的代码:

    #if defined _BSD_SOURCE || defined _SVID_SOURCE
    # define __USE_MISC 1
    #endif
    

    它告诉如果定义了“_BSD_SOURCE”或“_SVID_SOURCE”,那么 __USE_MISC 将被自动定义。

  3. 考虑您自己的代码的兼容性,在您将使用scandir()的文件的开始处(在#include < .h>||“ .h”之类的任何语句之前)添加语句(任何一个或两个)。

    #define _BSD_SOURCE  1
    #define _SVID_SOURCE 1
    
  4. 保存您的文件并制作。

于 2015-04-15T08:52:07.970 回答
0

尝试#include <sys/dir.h>归档以使用 scandir 并定义extern int alphasort(const void*,const void*);extern int alphasort();高于您的printFiles

另外-您应该将程序与标准库链接(希望已经完成)

于 2013-10-18T01:09:27.553 回答