var arg list to tempfile, зачем это нужно? - PullRequest
1 голос
/ 20 июля 2010

У меня есть этот код внутри конструктора класса (не написанного мной), и он записывает список переменных arg в файл tmp.

Интересно, а зачем это нужно?Tmpfile удаляется после того, как этот ctor выходит из области видимости, а список var arg находится внутри вектора m_str.

Может кто-нибудь предложить лучший способ сделать это без использования tmpfile?

Ответы [ 4 ]

2 голосов
/ 20 июля 2010

Это код C ++: я думаю, что вы, возможно, пытаетесь решить не ту проблему здесь.

Потребность во временном файле полностью исчезнет, ​​если вы решите использовать дизайн C ++ - esque вместо того, чтобы продолжатьиспользовать варагс.Может показаться, что для конвертации всех вызывающих сайтов в новый механизм может потребоваться много работы, но varargs предоставляет широкий спектр возможностей для неправильной передачи параметров, оставляя вас открытыми для коварных ошибок, не говоря уже о том, что вы не можете передать неТипы POD вообще.Я верю, что в долгосрочной (или даже среднесрочной) перспективе это окупится за надежность, ясность и простоту отладки.

Вместо этого попробуйте реализовать интерфейс потоков в стиле C ++, который обеспечивает безопасность типов и даже возможностьзапретить определенные операции при необходимости.

1 голос
/ 20 июля 2010

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

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

Редактировать: если изменение сигнатуры функции действительно слишком сложно для размышления, то вы, вероятно, захотите заменить vfprintf на vsnprintf. vsnprintf позволяет вам указать длину буфера (чтобы он не переполнял буфер) и возвращает количество символов, которые сгенерировали бы , если бы было достаточно места. Таким образом, использование будет почти таким же, как у вас сейчас, но избегайте генерации временного файла. Вы бы назвали его один раз, указав длину буфера 0, используйте возвращаемое значение (+1 для терминатора NUL), чтобы изменить размер буфера, а затем вызовите его снова, указав правильный размер буфера.

0 голосов
/ 20 июля 2010

У меня появляется тошнотворное чувство, но вы можете попробовать:

  FILE *fp=freopen("nul","w", stderr)
  int n = ::vfprintf( fp , fmt, varptr );
  fclose(fp);

(windows)

0 голосов
/ 20 июля 2010

Похоже, что временный файл используется в качестве места вывода для вызова :: vfprintf ().Это делается для получения длины отформатированной строки (плюс 1 для значения NULL).Затем изменяет размер m_str, достаточно большой, чтобы вместить отформатированную строку, которая заполняется из вызова :: vsprintf ().

Список var arg отсутствует в файле или в m_str.Форматированный вывод из printf () (и его варианты) находится в файле и в m_str.

...