【问题标题】:Directories outside of working directory not recocnized by S_ISDIRS_ISDIR 无法识别工作目录之外的目录
【发布时间】:2021-09-16 13:16:56
【问题描述】:

所以我使用 stat() 来检查目录,它工作得很好,直到我在 cwd 之外导航。然后目录被列为文件。

这是我创建文件列表的函数中的一个 sn-p。它在 SDL GUI 中实现。 目录应为红色,所有其他文件为蓝色。但是,例如,当我转到我的桌面时,所有目录都是蓝色的,而它们应该是红色的。

注意:fMenu 用作存储文件列表的缓冲区。路径改变时更新。

    DIR *dir;
    struct dirent *dd;
    struct stat sd;
    dir = opendir(fMenu.fPath[fMenu.mode]);
    for (int a = 0; a < 1023; a++) // clears file list
    {
        fMenu.fList[fMenu.mode][a].isDir = false;
        memset(fMenu.fList[fMenu.mode][a].fName, 0, strlen(fMenu.fList[fMenu.mode][a].fName));
    }
    for (int a = 0; (dd = readdir(dir)) != NULL && a < 1023; a++) // gets files and puts in file list array
    {
        stat(dd->d_name, &sd);
        if (S_ISDIR(sd.st_mode)) //////// something wrong with this?
        {
            fMenu.fList[fMenu.mode][a].isDir = true;
            strncat(fMenu.fList[fMenu.mode][a].fName, dd->d_name, strlen(dd->d_name));
        } else
        {
            strncat(fMenu.fList[fMenu.mode][a].fName, dd->d_name, strlen(dd->d_name));
        }
    }
closedir(dir);

在这里它被转换为 GUI 的纹理。

    for (int a = 0; a < 40; a++)
    {
        if (a == fMenu.pos)
        {
            if (fMenu.fList[fMenu.mode][a + fMenu.offset].isDir)
            {
                tempSurf = TTF_RenderText_Shaded(font, fMenu.fList[fMenu.mode][a + fMenu.offset].fName, Red, white);
            } else
            {
                tempSurf = TTF_RenderText_Shaded(font, fMenu.fList[fMenu.mode][a + fMenu.offset].fName, buttonColor, white);
            }
        } else
            {
                if (fMenu.fList[fMenu.mode][a + fMenu.offset].isDir)
            {
                tempSurf = TTF_RenderText_Solid(font, fMenu.fList[fMenu.mode][a + fMenu.offset].fName, Red);
            } else
            {
                tempSurf = TTF_RenderText_Solid(font, fMenu.fList[fMenu.mode][a + fMenu.offset].fName, buttonColor);
            }
        }
        SDL_DestroyTexture(fileDisplayTex[a]);
        fileDisplayTex[a] = SDL_CreateTextureFromSurface(renderer, tempSurf);
        SDL_FreeSurface(tempSurf);
        fileDisplayRect[a].w = strlen(fMenu.fList[fMenu.mode][a + fMenu.offset].fName) * 12;
    }

【问题讨论】:

  • 你没有检查stat的返回码。您可能无法正确构造那些其他目录文件的路径名,因此 stat 可能会失败,您的结果可能毫无意义。
  • readdir 只是给你单独的路径名。您可能想要构造 fMenu.fPath[fMenu.mode] ⊕ "/" ⊕ dd-&gt;d_name (我使用 ⊕ 表示字符串连接)。
  • 我强烈建议不要构建不必要的路径。您可以使用fstatat() 来获得理智的行为。此外,您可能不需要进行 任何 stat 类调用,因为在 Linux 上,struct dirent 已经包含 d_type 字段。
  • 我使用 stat 而不是内置的 d_type 的原因是为了使代码更通用。我在 windows 上写这个,不幸的是没有 d_type。
  • 此外,如果您正在考虑对这些目录使用递归,您可能希望跳过处理“。”和“..”基于 UNIX 的系统上的目录。

标签: c directory sdl dirent.h


【解决方案1】:

好的,感谢史蒂夫的这个:)

这是新代码

void getFileList()
{
    DIR *dir;
    struct dirent *dd;
    struct stat sd;
    dir = opendir(fMenu.fPath[fMenu.mode]);
    char fullPath[strlen(fMenu.fPath[fMenu.mode]) * 2];
    for (int a = 0; a < 1023; a++) // clears file list
    {
        fMenu.fList[fMenu.mode][a].isDir = false;
        memset(fMenu.fList[fMenu.mode][a].fName, 0, strlen(fMenu.fList[fMenu.mode][a].fName));
    }
    for (int a = 0; (dd = readdir(dir)) != NULL && a < 1023; a++) // gets files and puts in file list array
    {
        //// uses full path
        memset(fullPath, 0, strlen(fullPath));
        strncat(fullPath, fMenu.fPath[fMenu.mode], strlen(fMenu.fPath[fMenu.mode]));
        strncat(fullPath, "\\", 2);
        strncat(fullPath, dd->d_name, strlen(dd->d_name));
        stat(fullPath, &sd);
        //////////
        if (S_ISDIR(sd.st_mode))
        {
            fMenu.fList[fMenu.mode][a].isDir = true;
            strncat(fMenu.fList[fMenu.mode][a].fName, dd->d_name, strlen(dd->d_name));
        } else
        {
            strncat(fMenu.fList[fMenu.mode][a].fName, dd->d_name, strlen(dd->d_name));
        }
    }
    closedir(dir);
    return;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2015-11-09
    • 2010-11-26
    • 1970-01-01
    • 2021-05-13
    • 2014-07-10
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多