提问人:Default 提问时间:6/26/2023 最后编辑:Default 更新时间:6/26/2023 访问量:172
fopen() 无法打开文件
fopen() is unable to open file
问:
我正在尝试打开一个文件并阅读其中的内容。但是,我目前只是试图打开它。
这是我的代码:
void read_contents(char* file_path)
{
printf("\nOriginal path: %s\n", file_path);
// Trying to prefix the path with "." to indicate that the path is relative.
char prefix[1024] = ".";
strcat(prefix, file_path);
// Printing to make sure that prefix contains correct path.
printf("\nPath after concatenating: %s\n", prefix);
FILE* file = fopen(prefix, "r");
if (file == NULL)
{
perror("Error");
// Close the file and stop the function.
fclose(file);
return;
}
// Code to read the file...
// ...
// Code to read the file...
fclose(file);
}
这是输出:(请记住,它甚至没有到达阅读部分)
Original path: /input_files/file_1.txt
Path after concatenating: ./input_files/file_1.txt
Error: no such file or directory
这是我的目录结构:
root:
executable
input_files (this is a folder)
file_1.txt
可执行文件与名为“input_files”的文件夹位于同一级别。input_files内部是文本文件所在的位置。
其他事项:
- 我正在从终端运行正确的可执行文件。
- 传递给函数时路径正确。
- 我的文件夹和文件的结构和名称是正确的。
- 访问和读取文件的权限是正确的。
- “.”正确地添加到字符串的开头。
有了这一切,我仍然收到一个错误,说没有这样的文件或目录。谁能告诉我我错过了什么?
答:
我无法重现该错误,这可能意味着您当前的工作目录可能与预期不同。这是您应该提供的程序,而不是将打印出当前工作目录 (cwd) 的不完整代码片段:
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void read_contents(char* file_path) {
printf("Original path: %s\n", file_path);
char prefix[strlen(file_path)+2];
strcpy(prefix, ".");
strcat(prefix, file_path);
printf("Path after concatenating: %s\n", prefix);
FILE* file = fopen(prefix, "r");
if (!file) {
perror("Error");
char cwd[PATH_MAX];
getcwd(cwd, PATH_MAX);
printf("cwd: %s\n", cwd);
return;
}
fclose(file);
}
int main(void) {
read_contents("/input_files/file_1.txt");
read_contents("/input_files/non-existing.txt");
}
下面是一个示例运行:
Original path: /input_files/file_1.txt
Path after concatenating: ./input_files/file_1.txt
Original path: /input_files/non-existing.txt
Path after concatenating: ./input_files/non-existing.txt
Error: No such file or directory
cwd: /home/...
评论
在阅读了此类情况下所有可能和常见的解决方案后,这些解决方案在您的案例中不起作用,我唯一的猜测可能是传递给函数的格式错误的 C 字符串,乍一看可以被视为正确。 我设法在我的网站上重现了类似的问题,只是将格式错误的 C 字符串指针传递给了read_contents函数。
主要思想。假设您的 main 函数中有一些静态初始化的数组,其长度大于文件路径的长度。在我复制的案例中,我采用了包含 100 字节的字节数组。
char path2[100] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x02};
我也有
char path[] = "/file.txt" // strlen on this will result in 10 (includes \0)
将 9 个字节的内存从路径(不包括 \0)复制到 path2 缓冲区后
memcpy(path2, path, 9);
请注意,我已经为 path2 - byte 中的 null-terminator 字节准备了替换(它可以是任何垃圾值)
将内存从正确的缓冲区复制到 path2 缓冲区后。生成的字符串也是正确的,如果我们将其打印出来,我们会看到完全相同的字符串,但是,null 终止符之前的最后一个字节是0x02,而不是初始路径中的最后一个符号。
准确地说,path2 缓冲区在 memcpy 之后将如下所示。0x02
2F 66 69 6C 65 2E 74 78 74 02 00 .... 00
/ f i l e . t x t \0
而不是正确的
2F 66 69 6C 65 2E 74 78 74 00 .... 00
/ f i l e . t x t \0
当尝试打印出此字符串时,您甚至不会看到空字符,就好像备用字节不存在一样,但对于系统来说,它很重要 C:
调用您提供的函数时,我得到这种输出
artyom@artyom:~/workspace/fopenfail$ ./a.out
Strlen /file.txt = 10
Original path: /file.txt
Path after concatenating: ./file.txt
Error: No such file or directory
artyom@artyom:~/workspace/fopenfail$ ls
a.out file.txt main.c
artyom@artyom:~/workspace/fopenfail$
这是我用作示例的代码
void read_contents(char* file_path)
{
printf("\nOriginal path: %s\n", file_path);
// Trying to prefix the path with "." to indicate that the path is relative.
char prefix[1024] = ".";
strcat(prefix, file_path);
// Printing to make sure that prefix contains correct path.
printf("\nPath after concatenating: %s\n", prefix);
FILE* file = fopen(prefix, "r");
if (file == NULL)
{
perror("Error");
// Close the file and stop the function.
return;
}
// Code to read the file...
// ...
// Code to read the file...
fclose(file);
}
int main()
{
char path[] = "/file.txt";
char path2[100] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x02};
memcpy(path2, path, 9);
printf("Strlen %s = %d", path2, strlen(path2));
read_contents(path2);
return EXIT_SUCCESS;
}
希望这能提示调用者函数中出了什么问题。
评论
fopen()
fclose()
/
x
cat ./input_files/file_1.txt