【问题标题】:fopen() return "No such file or directory"fopen() 返回“没有这样的文件或目录”
【发布时间】:2017-09-15 09:11:36
【问题描述】:

我对 C 中的 fopen() 函数有一些问题。

我是解析目录并将所有路径放入 char 数组(char**)。之后我应该打开所有这些文件。和... fopen 对某些文件返回“没有这样的文件或目录”。我真的不明白,为什么。

  1. 所有路径都是正确的。我查过了。
  2. 我拥有所有权限 打开这些文件。
  3. 如果我从错误日志复制文件路径并尝试 通过我的程序只打开这个文件 - 它可以工作。
  4. 其他 程序不适用于这些文件(我认为)。

我能做错什么?

int main(int argc, char *argv[]){
    char** set = malloc(10000*sizeof(char*));
    char* path = argv[1];
    listdir(path, set); /* Just parse directory. Paths from the root. No problem in this function.  all paths in the variable "set" are right */
    int i=0;
    while(i<files){ /* files is number of paths */
        FILE* file = fopen(set[i++],"rb");
        fseek(file, 0L, SEEK_END);
        int fileSize = ftell(file);
        rewind(file);
        /*reading bytes from file to some buffer and close current file */
        i++;
    }
}

【问题讨论】:

  • 你做错的是你没有提供minimal reproducible example
  • 请出示您的代码。
  • 调试器。打破 fopen()。逐字节检查 set[] 数组。如果这很尴尬,则 strcpy() 将数组元素转换为本地 char 数组(例如文件路径 [256]),然后检查它。找出路径不正确的原因并修复它。
  • 所有路径都是正确的。我查过了。 那么,一个可能被数亿人(如果不是更多人)使用的操作系统是错的吗?您没有发布的唯一代码和示例是否正确?
  • @tFNiYaFF - 相同吗?没有多余的不可打印的字符?没有隐藏的CR,LF?只是 NUL 终止符紧随其后的绝对路径?

标签: c fopen


【解决方案1】:
  1. 您将“i”增加两次。可能弄错了?
  2. 您可以使用 stat() 获取不打开文件的大小。
  3. ftell() 返回“long”,不要将其转换为“int”,因为它可能会缩短并且您会丢失正确的值。

试试这个代码:

#include <stdio.h>
#include <sys/stat.h>

/* example of listdir, replace it with your real one */
int listdir(const char *path, char *set[])
{
    set[0] = "0.txt";
    set[1] = "1.txt";
    set[2] = "2.txt";
    set[3] = "3.txt";
    set[4] = "4.txt";

    return 5;
}

int main(int argc, char *argv[]) {
    int files;
    char *path = argv[1];
    char **set = malloc(1000 * sizeof(char *));

    files = listdir(path, set);

    for (int i = 0; i < files; i++) {
        struct stat st;
        stat(set[i], &st);
        printf("FileSize of %s is %zu\n", set[i], st.st_size);
    }
    free(set);
}

【讨论】:

  • 不要尝试使用不兼容的 char **name 作为 char *name[]。 ?!?!?!?请解释一下。
  • 安德鲁,请忽略那句话,这是愚蠢的想法:)
【解决方案2】:

(我猜你是在某个 Posix 系统上,希望是 Linux)

可能您的listdir 是错误的。 FWIW,如果您在其中使用readdir(3),则需要连接目录名和文件名(在两者之间使用/,可能为此使用snprintf(3)asprintf(3))。

当然,

    FILE* file = fopen(set[i++],"rb"); ////WRONG

是双重错误。首先,您将i++ 增加两次(现在还为时过早)。然后,您应该阅读fopen(3) 并处理失败情况,至少使用:

   char* curpath = set[i];
   assert (curpath != NULL);
   FILE* file = fopen(curpath, "rb");
   if (!file) { perror(curpath); exit(EXIT_FAILURE);  };

测试fopen 的结果是否失败是强制性的。请注意,我将 same curpath 传递给 perror(3) 失败。

您可能还想检查您当前的working directory 是否符合您的预期。为此使用getcwd(2)

也可以使用 strace(1)(在 Linux 上)来了解您的程序执行了 system calls 什么。

【讨论】:

    猜你喜欢
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 2014-02-13
    相关资源
    最近更新 更多