显然
fdopen
需要使用编译标准的 POSIX/gnu99。我希望留在 C99。
我遇到这个问题是因为我使用
open()
创建文件描述符,然后(因为我使用 fgets()
)我需要一个通过 fdopen()
生成的文件指针。不幸的是,fdopen()
在 C99 中不可用。
有没有办法从符合 C99 的描述符中获取
FILE
结构?
有没有办法从符合 C99 的描述符中获取
结构?FILE
如果“C99 兼容”是指仅依赖 C99 指定的 C 标准库的功能,则否。不过没关系,因为如果只依赖C99的标准库,根本就没有办法得到文件描述符。通过 C
FILE
对象管理的流是 C99 定义的文件的唯一表示形式。
另一方面,如果您正在谈论将自己限制在 C99 的语法和语义上,但不一定是它指定的标准库函数,那么是的:使用
fdopen()
。它完全符合您描述的目的。
由于您似乎正在使用 gcc,可能出现问题是因为您想使用
-std=c99
选项编译以禁用语言扩展,并且您发现这也禁用(或至少不启用)某些函数的声明,包括fdopen()
。这是因为 -std
选项会影响一些标准 feature 测试宏 的默认值。 fdopen()
的文档说它需要多种功能测试宏之一:值大于 0 的 _POSIX_C_SOURCE
,或 _XOPEN_SOURCE
,或 _POSIX_SOURCE
。使用 -std=gnu99
您可以获得所有服务于此目的的设置,但是使用 -std=c99
您不会获得任何可以完成工作的定义。
如果您想要最新版本 POSIX 的所有库功能(由您的 glibc 提供),那么您应该确保
_POSIX_C_SOURCE
定义为值 200809L
(截至 POSIX.1-2017)。由于这种依赖性是源代码的特征,而不是编译条件的特征,因此您应该在源文件的最开头放置适当的宏定义(也就是说,不要为此依赖编译选项)。例如:
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <fcntl.h>
// ...
应该在任何标题之前定义宏
#include
d.
然后您应该能够使用
gcc -std=c99
进行编译,并且还具有 fdopen()
的声明。
fdopen()
函数是 POSIX 的一部分,而不是 C99 的一部分。如果你在严格的 C99 模式下编译你的代码,比如 -std=c99
,你将不会得到它。
这当然是意料之中的——
int
文件描述符也不是 C99 的一部分。 fdopen()
的重点是与 POSIX 文件描述符的互操作性。
获得该功能的方法是在包含标题之前定义正确的“功能测试宏”。在你的文件的顶部做:
#define _POSIX_C_SOURCE 1
#include <stdio.h>
// use fdopen() here
您可以在手册页中找到有关这些要求的信息:
https://linux.die.net/man/3/fdopen
glibc 的功能测试宏要求(参见 feature_test_macros(7)):
fdopen(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
“C99-compliance”是一个有趣的术语。如果你在 POSIX 或类似 POSIX 的系统(Linux、WSL)上,那么你有
int
文件描述符和 fdopen()
,一切都会正常工作。如果您尝试编写在任何符合 C99 的实现上运行的代码,那么您显然不能使用 fdopen()
——而且 open()
也不是 C99 的一部分。
你不需要为
open()
这样做的原因是因为 open()
通过 <fcntl.h>
暴露,这不是 C99 的一部分。