有什么方法可以使用 C99 获得 fdopen 功能?

问题描述 投票:0回答:2

显然

fdopen
需要使用编译标准的 POSIX/gnu99。我希望留在 C99。

我遇到这个问题是因为我使用

open()
创建文件描述符,然后(因为我使用
fgets()
)我需要一个通过
fdopen()
生成的文件指针。不幸的是,
fdopen()
在 C99 中不可用。

有没有办法从符合 C99 的描述符中获取

FILE
结构?

c posix c99 gnu99
2个回答
1
投票

有没有办法从符合 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()
的声明。


0
投票

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 的一部分。

© www.soinside.com 2019 - 2024. All rights reserved.