Linux имеет эту хорошую функцию dprintf
:
Функции
dprintf()
иvdprintf()
(как найдено в glibc2 библиотеке), точные аналогиfprintf()
иvfprintf()
, за исключением того, что они производят к дескриптору файла fd вместо к данному потоку.
однако, поскольку тот же самый источник указывает:
Эти функции являются расширениями GNU, не в C или POSIX. Очевидно, имена были плохо выбраны. Многим системам (как MacOS) назвали несовместимые функции
dprintf()
, обычно некоторая отладочная версияprintf()
, возможно, с прототипом как
void dprintf (int level, const char *format, ...);
где первый параметр является уровнем отладки (и вывод к
stderr
). Кроме того,dprintf()
(илиDPRINTF
) также популярное макро-название отладкиprintf
. Так, вероятно, лучше избежать, чтобы эта функция в программах намеревалась быть портативной.
Как я могу сделать установку, которая будет безопасно звонить dprintf
то, что я хочу, если это существует, или сбой для компиляции с некоторым довольно нормальным сообщением об ошибке, если та функция не существует? Я предполагаю, что сделал бы что-то вроде этого:
#ifdef SOMETHING
#define Dprintf dprintf
#else
#error "no dprintf"
#endif
но я не знаю что SOMETHING
должен быть. Я предполагаю, что мог ограничить его просто Linux, но я мог сделать это более свободным?
выглядит как DPRINTF ()
на самом деле в POSIX.1-2008 (с требуемым семантикой), чтобы вы могли сделать это:
#if !defined(__GLIBC__) && _POSIX_C_SOURCE < 200809
#error "dprintf may not exist, or may be wrong"
#endif
__ GLIBC __
определяется, если вы используете систему сборки GNU. Это, вероятно, так же безопасно, как вы можете быть без написания небольшой тестовой программы.
Вы можете сделать тест AutoConf, если вы используете AutoTools для вашей BuildSystem.
AC_LANG([C])
AC_USE_SYSTEM_EXTENSIONS
AC_ARG_WITH([dprintf],
[AS_HELP_STRING([--with-dprintf],
[Assume that dprintf prints to a specified file descriptor])],
[], [with_dprintf=check])
AS_IF([test "x$with_dprintf" = xcheck],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <stdio.h>
#include <string.h>
int debug_level;
]], [[
char msg[] = "Hello, world!\n";
char rcv[sizeof(msg)] = "";
FILE *f = tmpfile();
int fd = fileno(f);
debug_level = fd - 1;
dprintf(fd, "%s", msg);
fseek(f, 0, SEEK_SET);
fread(rcv, 1, sizeof(msg), f);
return strcmp(msg, rcv);
]]
)], [with_dprintf=yes])])
AS_IF([test "x$with_dprintf" = xyes],
[AC_DEFINE([HAVE_DPRINTF], [1],
[dprintf prints to a specified file descriptor])])
(позволяя - с деплинфом
или - без креннф
, когда кросс-компиляция, как AC_RUN_IFELSE
недействителен в этих случаях. )
FDOPEN не в стандарте C, но это в в POSIX.2, а затем. Я не вспоминаю ни одного Unix, который не имеет этого - черт, даже окна есть.
int fdprintf(int fd, char *fmt, ...) {
va_list ap;
FILE *f = fdopen(fd);
int rc;
va_start(ap, &fmt);
rc = vfprintf(f, fmt, ap);
fclose(f);
va_end(ap);
return rc;
}
Конечно, если вы знаете, к какому файловому дескриптору вы будете печатать, просто удерживайте файл *
.
Одной из основных причин Выбор приходит в последний раз, является создание работы IntelliSense. Приведя источник последовательности в первую очередь (от оператора), Intellisense может работать должным образом.
-121--1422465- Тест AutoConf может проверить, является ли DPRINTF (1, «Blablabla»)
[11655] , и
DPRINTF (-1, «BLABLABLA»)
неиспользуется интересным способом или пишет на Стдерр.
Если LIBC дает вам неправильно DPRINTF ()
, вы могли бы реализовать его сверху SNPRINTF ()
(или даже лучше ASPRINTF ()
) и Написать ()
. И затем упомяните свой «DPRINTF.O» к линкеру, чтобы он предпочитал вас на LIBC.
Если вы хотите лучшее имя, я предлагаю FDPrintF ()
.