1

我有检查文件是否存在的功能:

int file_exists(char *filename)
{
    struct stat buffer;
    int i = stat(filename, &buffer);
    if (i == 0) {
        return 1;
    }
    return 0;
}

它适用于完整路径,但我想检查用户主目录中是否存在文件,如果不存在 - 在 /etc 目录中。怎么做?

4

4 回答 4

2
int 
file_exists(const char *basename)
{
    static const char *dirs[] = { "/etc", "/home/username" };
    char buf[MAX_PATH_LENGTH + 1];
    size_t i;
    struct stat dummy;

    for (i = 0; i < sizeof dirs / sizeof dirs[0]; ++i) {
        (void)snprintf(buf, sizeof buf, "%s/%s", dirs[i], basename);
        if (!stat(buf, &dummy)) return 1; 
    }

    return 0;
}

请注意,如果路径加上文件名的长度超过 MAX_PATH_LENGTH 个字符,这将失败(即搜索错误的文件)。您可以检查的返回值snprintf来捕捉它。

如果您想避免查找目录/sockets/...,可以将if行更改为

if (!stat(buf, &dummy) && S_ISREG(dummy.st_mode)) return 1; 

正如亚当·罗森菲尔德所指出的那样。在这种情况下,您可能想要重命名dummy为更合适的名称(也许sb)。

于 2013-07-10T23:39:27.703 回答
0

仅将“文件名”作为输入,然后使用 strcat 创建完整路径名 - 如下所示:

int file_exists(char *filename)
{
    struct stat buffer;
    char fullpath[50], *path;
    path = "/home/Nips/"
    if ((strlen(path) + strlen(filename)) >= 50) {
        printf("filename too long!\n");
        return 0;
    }
    strcpy(fullpath, path);
    strcat(fullpath, filename);
    if (stat(fullpath, &buffer) == 0) {
        return 1;
    }
    if (errno == ENOENT) {
        path = "/etc/";
        strcpy(fullpath, path);
        strcat(fullpath, filename);
        if (stat(fullpath, &buffer) == 0) {
            return 1;
        }
        if (errno == ENOENT) {
            printf("File not found!\n");
            return 0;
        }
    }
    printf("Error finding File!\n");
    return 0;
}

注意:代码未经测试,这只是为了给你一个提示。在实施时进行适当的健全性检查。希望这会给你一些想法!

于 2013-07-10T22:26:56.247 回答
0

使用该errno值,ENOENT如果文件不存在。

#include <errno.h>
int file_exists(char *filename)
{
    struct stat buffer;
    int i = stat(filename, &buffer);
    if (i == 0) {
       return 1;
    }
    if (errno == ENOENT)
       printf("%s : file not found\n", buffer);
    return 0;
}

对于您的问题:chdir如果您不想将目录与文件名连接起来,请使用。

于 2013-07-10T21:46:36.213 回答
0

始终提供路径的完整地址,或当前目录上的 ./。

另外,根据这个类似的问题access(pathname, mode)函数可以满足您的需要。改用它。成功时返回 0,失败时返回 -1。由于 access() 完全符合您的需要,因此您不必重新实现它。

请注意,最常见的模式如下:

F_OK,用于检查文件是否存在。

R_OK,用于阅读。

W_OK,用于写作。

X_OK,用于读取、写入和执行权限。

此外,例如,如果您需要检查读写权限,则可以在 R_OK 和 W_OK 之间设置按位或(甚至在每三个 R_OK、W_OK 或 X_OK 之间)

如需更多信息,请在您的终端上输入man access,或访问上面的链接。

当心:access() 是 unistd.h 库的一部分,即 POSIX 标准。如果您需要在其他系统下使用它,您可能需要包含不同的库。

于 2013-07-10T22:37:12.793 回答