在不存在的目录中打开文件 c 与 c++
open a file in a non existing directory c versus c++
我尝试在 C++ 中打开一个不存在的目录中的文件,由于某种原因我的应用程序没有崩溃。我发现有点 "weird" 因为 我习惯了 C,等效程序确实崩溃了 。这是我的 C++ 版本,后面是等效的 C 版本:
$ cat main.cpp
#include <fstream>
int main(int argc, char **argv)
{
std::ofstream f("/home/oren/NON_EXISTING_DIR/file.txt");
f << "lorem ipsum\n";
f.close();
printf("all good\n");
}
$ g++ main.cpp -o main
$ ./main
all good
当我尝试用 C 做同样的事情时,我得到了一个段错误:
$ cat main.c
#include <stdio.h>
int main(int argc, char **argv)
{
FILE *fl = fopen("/home/oren/NON_EXISTING_DIR/file.txt","w+t");
fprintf(fl,"lorem ipsum\n");
fclose(fl);
printf("all good\n");
}
$ gcc main.c -o main
$ ./main
Segmentation fault (core dumped)
这是为什么?
"我习惯了C", 但后来"[.. .] 在 C++ 中 " - 好吧,C++
不是 C
,但这与这里无关。首先,看一下 - 在设置 failbit 后,写入未打开的流(这里就是这种情况)将被忽略。
然而,在您的 C
示例中,问题是如果 fopen
失败,它 returns 一个 NULL
指针。然后你将它传递给 fprintf
。这就是未定义行为1 发生的地方。 C++
示例中没有这样的东西。
1请注意 C
示例 不保证 SEGFAULT。未定义的行为是未定义的。
使用函数的文档是关键。在这两种情况下,程序都无法打开文件。但是由于某些原因,C++ 库的概念不允许它在构造函数中崩溃。 ofstream
实际上使用相同的 fopen
或类似的功能。
让我们看看手册是怎么说的:
Upon successful completion fopen(), fdopen() and freopen() return a
FILE pointer. Otherwise, NULL is returned and errno is set to
indicate the error.
所以你必须检查返回值是否为 NULL,否则你有一个未定义的行为。 ofstream
为您做到了,在对象初始化期间不会发生未定义的行为。
我尝试在 C++ 中打开一个不存在的目录中的文件,由于某种原因我的应用程序没有崩溃。我发现有点 "weird" 因为 我习惯了 C,等效程序确实崩溃了 。这是我的 C++ 版本,后面是等效的 C 版本:
$ cat main.cpp
#include <fstream>
int main(int argc, char **argv)
{
std::ofstream f("/home/oren/NON_EXISTING_DIR/file.txt");
f << "lorem ipsum\n";
f.close();
printf("all good\n");
}
$ g++ main.cpp -o main
$ ./main
all good
当我尝试用 C 做同样的事情时,我得到了一个段错误:
$ cat main.c
#include <stdio.h>
int main(int argc, char **argv)
{
FILE *fl = fopen("/home/oren/NON_EXISTING_DIR/file.txt","w+t");
fprintf(fl,"lorem ipsum\n");
fclose(fl);
printf("all good\n");
}
$ gcc main.c -o main
$ ./main
Segmentation fault (core dumped)
这是为什么?
"我习惯了C", 但后来"[.. .] 在 C++ 中 " - 好吧,C++
不是 C
,但这与这里无关。首先,看一下
然而,在您的 C
示例中,问题是如果 fopen
失败,它 returns 一个 NULL
指针。然后你将它传递给 fprintf
。这就是未定义行为1 发生的地方。 C++
示例中没有这样的东西。
1请注意 C
示例 不保证 SEGFAULT。未定义的行为是未定义的。
使用函数的文档是关键。在这两种情况下,程序都无法打开文件。但是由于某些原因,C++ 库的概念不允许它在构造函数中崩溃。 ofstream
实际上使用相同的 fopen
或类似的功能。
让我们看看手册是怎么说的:
Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer. Otherwise, NULL is returned and errno is set to indicate the error.
所以你必须检查返回值是否为 NULL,否则你有一个未定义的行为。 ofstream
为您做到了,在对象初始化期间不会发生未定义的行为。