Есть ли указатель файла (FILE *), который ничего не указывает? - PullRequest
2 голосов
/ 12 сентября 2011

По некоторым причинам мне нужен указатель файла (FILE *), который ничего не указывает.Это означает, что я могу передать его в функцию fprintf, а fprintf игнорировать указатель файла.

, например:

void my_function()
{
  FILE* nothing = NULL; // NULL is not correct.
  int n = fprintf(nothing, "PI = %f", 3.14); // Note: When nothing = NULL, error ocured.
}

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

Ответы [ 5 ]

7 голосов
/ 12 сентября 2011

Чтобы решить вашу реальную проблему (указанную в комментариях), используйте snprintf вместо printf, при условии, что она доступна в вашей реализации C ++ (что не гарантируется в C ++ 03).Передайте нулевой указатель для буфера и 0 для размера.Ничего не написано, но возвращаемое значение - это длина отформатированной строки (исключая терминатор nul).

[Редактировать: упс, я забыл, что snprintf в Windows не соответствует C99.В случае усечения возвращается ошибка, а не требуемая длина.Я не знаю, что они собираются делать с тем фактом, что C ++ 0x требует соответствия C99 snprintf.]

Чтобы ответить на ваш вопрос, вы можете открыть /dev/null в UNIX-подобномсистемы или nul в Windows.Пишет в результате FILE* не имеет никакого эффекта.Однако портативного нуль-устройства не существует.

6 голосов
/ 12 сентября 2011

номер

Ваш код вызовет исключение во время выполнения. Например, вы можете использовать /dev/null, если вы работаете в операционной системе, которая поддерживает его, но нет ничего подобного встроенному в C ++.

0 голосов
/ 12 сентября 2011

Вы делаете ошибку проектирования.

Очевидно, что вам нужно знать количество символов, необходимое для написания вашего номера.

Вы используете _ * printf_ для этого, что является хорошей идеей. Вы просто хотите вычислить количество символов "написано", следовательно, необходимо. Но вы не хотите, чтобы что-либо отображалось, поэтому вы укололись fprintf вместо printf . Но fprintf не работает без ФАЙЛА для записи в ...

Как сказал Стив, вам лучше использовать snprintf () , который записывает в строку в памяти.

Как говорит Стив, snprintf , снабженный строкой NULL, должен работать должным образом, за исключением окон. Затем на окнах, просто предоставьте ему временную строку, которую вы потом отбросите.

size_t computeNumCharsNeededToPrintMyStuff(double d)
{
    size_t ret = 0;
    size_t maxBuffSize = 100; // should be plenty enough

    char *tmpBuff = new char[maxBuffSize ];
    ret = snprintf(tmpBuff, maxBuffSize, "PI = %f", d);
    delete[] tmpBuff;

    return ret;
}

Тогда вы просто позвоните:

n = computeNumCharsNeededToPrintMyStuff(3.14)

(Эта функция может быть улучшена для вычисления размера, необходимого для отображения чего-либо, но я бы пока оставил это простым).

0 голосов
/ 12 сентября 2011

Хотя, как сказал NirMH, вы можете заключить его в if (nothing != NULL), есть и другой способ. Вы можете открыть файл в режиме чтения (с помощью "r"), и когда вы отправляете его на fprintf, запись игнорируется (Правка: как обсуждалось в комментариях, не забудьте установить n=0, если он был отрицательным, как возвращено fprintf).

Я лично предлагаю первый способ, хотя. Единственная причина, по которой я могу сделать второе, - это если я не могу изменить функцию.

Если вам все равно, зависит ли ваш код от системы, вы можете использовать /dev/null в Linux, nul в Windows и т. Д.,

0 голосов
/ 12 сентября 2011

почему бы не обернуть вызов метода fprintf оператором if (NULL != nothing)?

...