ФАЙЛ*, который никуда не денется

Есть ли способ получить объект потока C (объект FILE*), который ни на что не указывает?

Я знаю, что fopen("/dev/null","w"); сработает, но мне интересно, есть ли лучший способ.

Предпочтительно, чтобы эти биты помещали данные на более высокий уровень, чем уровень posix, а также были более переносимыми.


person BCS    schedule 13.12.2009    source источник
comment
Зачем вам это нужно? Вероятно, есть лучший способ сделать то, что вы пытаетесь сделать.   -  person Andrey    schedule 13.12.2009
comment
У меня есть журнал, который ведет к stderr, и я хочу отключить его с помощью флага. Я действительно предпочел бы не делать с этим больше, чем изменить переменную, которая передается на fprintf.   -  person BCS    schedule 13.12.2009
comment
Аналогично stackoverflow.com/questions/1741191/. Реализация stdio, кажется, всегда поддерживает такие вещи, но API не предоставляет хороший способ ее использования.   -  person Edmund    schedule 13.12.2009


Ответы (2)


Нет: /dev/null в Unix и NUL: в Windows (при отсутствии Cygwin или эквивалента) — лучший способ сделать это.

(В исходной версии вопроса упоминалось fopen("/dev/null","o");, но с тех пор оно было исправлено.)
Да, и флаг "o" для fopen() непереносим. Переносимые формы включают в себя флаговые символы r, w, a, b, + в различных комбинациях.

person Jonathan Leffler    schedule 13.12.2009
comment
Хорошо, я знал, что должен был посмотреть это. Я работал по памяти. - person BCS; 13.12.2009
comment
@Anacrolix: я понятия не имею, что делает 'o'; он не переносим и не применим к имеющимся у меня системам ... Я думаю, что он был задуман как вариант «w». - person Jonathan Leffler; 13.12.2009
comment
почему : - в Windows нулевое устройство называется NUL (см., например, msdn.microsoft.com/en-us/library/ для получения полного списка зарезервированных имен файлов) - person Christoph; 13.12.2009
comment
@Christoph: потому что у меня была иллюзия, что двоеточие необходимо или желательно, чтобы указать, что это именно то устройство, которое вам нужно. Если это не удается с двоеточием, это исправимая ошибка в моем ответе; если толстая кишка просто не нужна, то спишите это на дурную привычку, приобретенную где-то в прошлом тысячелетии. Я не совсем одинок в своем понимании — см. en.wikipedia.org/wiki/DOS#Reserved_device_names< /а>. - person Jonathan Leffler; 13.12.2009

У меня есть журнал, который идет в stderr, и я хочу отключить его с помощью флага. Я бы предпочел не делать с этим больше, чем изменить переменную, которая передается в fprintf

а) Функция-обертка

logging = TRUE;
void debugprint(...)
{
    if (logging)   
    {
        fprintf(stderr, ...);
    }
}

б) Я думаю, что fprintf вернется, если вы дадите ему нулевой указатель. Не помню - попробуйте. Тогда все, что вам нужно сделать, это изменить указатель :)

person Pod    schedule 13.12.2009
comment
а) за такую ​​большую работу я мог бы переключиться на настоящую систему регистрации. б) на это стоит обратить внимание +1 - person BCS; 13.12.2009
comment
б) быстрый осмотр показывает, что fprintf(NULL,""); не удастся. - person BCS; 13.12.2009
comment
Все, что вам нужно сделать, это добавить одну функцию и найти + заменить все экземпляры для fprintf (stderr). - person Pod; 13.12.2009
comment
Я думал, что это возможно. C std lib имеет тенденцию не проверять свои параметры. - person Pod; 13.12.2009
comment
Передача нулевого указателя файла в fprintf() приводит к неопределенному поведению и обычно к сбою и дампу ядра в Unix-подобных системах. - person Jonathan Leffler; 13.12.2009