var arg list to tempfile,为什么需要?

时间:2010-07-20 13:21:02

标签: c++ variadic-functions temporary-files

我在类的构造函数(不是由我编写)中包含此代码,并将变量arg列表写入tmp文件。

我想知道为什么需要这个?在此ctor超出范围并且var arg列表位于m_str向量内时,将删除tmpfile。

有人可以在没有使用tmpfile的情况下建议更好的方法吗?

DString(const char *fmt, ...)
    {

        DLog::Instance()->Log("Inside DString with ellipses");

        va_list varptr;
        va_start(varptr, fmt);
        FILE *f = tmpfile();
        if (f != NULL)
        {
            int n = ::vfprintf(f, fmt, varptr) + 1; 
            m_str.resize(n + 1);
            ::vsprintf(&m_str[0], fmt, varptr);
            va_end(varptr);
        }
        else
            DLog::Instance()->Log("[ERROR TMPFILE:] Unable to create TmpFile for request!");
    }

4 个答案:

答案 0 :(得分:2)

这是C ++代码:我想你可能正试图在这里解决错误的问题。

如果你考虑使用C ++设计而不是继续使用varargs,那么对temp文件的需求就会完全消失。将所有调用站点转换为使用新机制似乎需要做很多工作,但是varargs提供了多种错误传递参数的可能性,让您可以接受隐藏的错误,更不用说你不能通过非完全是POD类型。我相信在长期(甚至中等)的条件下,它将在可靠性,清晰度和易于调试方面获得回报。

而是尝试实现C ++风格的流接口,该接口提供类型安全性,甚至可以在需要时禁止某些操作。

答案 1 :(得分:1)

它只是将临时文件用作可以写入不会溢出的内容的地方,因此它可以测量长度,然后为字符串分配足够的空间,最后将实际输出存入字符串。 / p>

我至少会考虑用iostreams风格的界面替换当前的printf风格界面是多么困难,这样可以轻松避免给所有iostreams的常见好处(类型安全,可扩展等)

编辑:如果更改函数的签名实在太难以考虑,那么您可能希望将vfprintf替换为vsnprintfvsnprintf允许您指定缓冲区长度(因此它不会超出缓冲区)并返回如果有足够的空间,生成的字符数。因此,使用情况几乎与您现在的情况相同,但避免生成临时文件。一旦指定缓冲区长度为0,就调用它,使用返回值(NUL终止符为+1)来调整缓冲区大小,然后再次调用它指定正确的缓冲区大小。

答案 2 :(得分:0)

它似乎使用临时文件作为:: vfprintf()调用的输出位置。它可以获得格式化字符串的长度(加上NULL为1)。然后调整m_str的大小,以保存格式化的字符串,该字符串从:: vsprintf()调用中填充。

var arg列表不在文件中或m_str中。 printf()(及其变体)的格式化输出位于文件和m_str。

答案 3 :(得分:0)

我有一种不安的感觉,但你可以尝试:

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

(窗口)