C &引用;fprintf“-用于文件描述符的like函数(即int fd而不是file*fp)

C &引用;fprintf“-用于文件描述符的like函数(即int fd而不是file*fp),c,file-io,printf,posix-api,C,File Io,Printf,Posix Api,也许我只是错过了它,但是对于文件描述符,是否有一个与fprintf等效的函数,或者甚至没有一种在它们之间临时切换的方法?您可以查看(GNU扩展,而不是C或POSIX中的扩展): 函数dprintf()和vdprintf() (如glibc2库中所示)是 fprintf()和 vfprintf(),但它们输出到 文件描述符fd,而不是 给定的流 编辑正如各位在评论中指出的那样,POSIX 2008标准化了这些功能。不,没有标准功能,但两者的功能不同。fprinft作为stdio的一部分,执行缓冲区

也许我只是错过了它,但是对于文件描述符,是否有一个与fprintf等效的函数,或者甚至没有一种在它们之间临时切换的方法?

您可以查看(GNU扩展,而不是C或POSIX中的扩展):

函数dprintf()和vdprintf() (如glibc2库中所示)是 fprintf()和 vfprintf(),但它们输出到 文件描述符fd,而不是 给定的流


编辑正如各位在评论中指出的那样,POSIX 2008标准化了这些功能。

不,没有标准功能,但两者的功能不同。fprinft作为stdio的一部分,执行缓冲区读写、支持ung等操作。使用fd绕过所有这些操作,直接调用操作系统

所以它们不能互换。如果没有其他任何东西,它们之间的触发器将破坏stdio缓冲。没有C或POSIX(编辑:2008年之前)标准函数对文件描述符执行
printf
,但是您可以使用POSIX标准
fdopen(int desc,const char*模式)
将文件描述符作为
文件*
打开。我不确定直接使用描述符的支持有多好,但我猜如果您先刷新缓冲区,它可能会起作用


当然,您可以使用类似于
vsprintf
的东西来实现自己的功能,但显然,您必须处理好缓冲

您可以将文件描述符作为普通文件打开,该文件可由
fprintf()
处理。

由于
dprintf
不是POSIX函数,因此如果存在可移植性问题,可以使用以下方法:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>

int
fdprintf ( int fd, size_t bufmax, const char * fmt, ... )
{
  char * buffer;
  int n;
  va_list ap;

  buffer = ( char * ) malloc ( bufmax );
  if ( !buffer )
    return 0;

  va_start ( ap, fmt );
  n = vsnprintf ( buffer, bufmax, fmt, ap );
  va_end ( ap );

  write ( fd, buffer, n );
  free ( buffer );
  return n;
}
#包括
#包括
#包括
#包括
int
fdprintf(整数fd,大小bufmax,常量字符*fmt,…)
{
字符*缓冲区;
int n;
va_列表ap;
缓冲区=(char*)malloc(bufmax);
如果(!缓冲区)
返回0;
va_启动(ap、fmt);
n=vsnprintf(缓冲区、bufmax、fmt、ap);
va_端(ap);
写入(fd,缓冲器,n);
自由(缓冲);
返回n;
}

最有可能的情况是检查
write
的返回值,但您得到了大致的想法。显然,这不像
文件*
例程那样缓冲;我在寻找更多的格式说明符和构建将写入文件描述符的字符数据的能力,而不是担心在写入数据时缓冲数据。

这是我的想法,但不是100%确定。除了。。。您可以执行
fdopen
操作,只要您记得在需要时执行
flush()
,触发器就可以正常工作。可能,但不一定,如果您想换个位置,可能无法工作,而且…谢谢!非常有趣,我不知道这些存在。我也不知道。因为这个应用程序只在Linux上运行,这可能是我需要的。跨平台兼容性不是一个问题,因此使用GNU扩展应该可以。如果可移植性不是一个问题,那么就使用这些功能。事实上,POSIX 2008标准化了这些功能。我想使用fdopen,但真的不想“打开”另一个句柄,特别是因为IIRC在该句柄上调用fclose也将关闭底层文件描述符。这可能是我正在处理的代码的问题,因为例程可能会得到一个文件描述符或套接字句柄。@威尔:您可以
fdopen
dup
获得一个处理过的文件,这样关闭操作就不会影响您的原始设置fd@Hasturkun:是的,我忘了dup。不是我经常使用的那些函数之一。
dprintf
是POSIX(从2008年开始),而静默截断数据的函数通常是一个非常糟糕的主意。至少循环较大的缓冲区,直到成功或返回失败…这很酷。这里我的gcc版本稍旧一些,仍然显示
dprintf
只是一个GNU扩展。