fprintf和vfprintf在C++中有什么区别?

Kni*_*ard 4 c c++ printf access-violation

我无法找到以下问题的答案,而且我遇到了与功能有关的一些问题.

我的主要编程是在C#中完成的,在学习时从未真正学过C++,但在我目前的工作中,我还要做一些C++编程.

大多数C++编程都是由一名前员工完成的,他还创建了一个日志功能.

偶尔这个函数会导致错误(访问冲突) - 这不会向用户显示,但我在通过调试器运行代码时看到它.

当错误发生时,它指向这行代码:

vfprintf( LogFile, fmt, va );
Run Code Online (Sandbox Code Playgroud)

然后我仔细研究了之前和之后的代码,并将上面的代码置于上下文中,代码是:

void FileLog( char *fmt, ... )
{
  va_list       va;
  struct  time  t;
  struct  date  d;
  long          clk;
  static int    ReEntrant = 0;

  if( FileLogEnabled == false )
    return;

  ReEntrant++;
  if( ReEntrant > 1 )
    return;

  if( LogFile == NULL )
    LogFile = fopen( LogFileName, "a+" );
  if( LogFile != NULL )
  {
    gettime( &t );
    getdate( &d );
    fprintf( LogFile, "\n%d-%02d-%02d %2d:%02d:%02d.%02d0> ", d.da_year, d.da_mon, d.da_day, t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund );

    va_start( va, fmt );
    vfprintf( LogFile, fmt, va );
    va_end( va );

    fflush( LogFile );
    ...
  }
  ReEntrant = 0;
}
Run Code Online (Sandbox Code Playgroud)

实际上我不明白为什么需要它(如果它是?)同时调用fprintf然后调用vfprintf?我认为第一个fprintf调用会将格式化的字符串写入流(文件),这就足够了吗?

一点点解释或一些信息将不胜感激:)

编辑:在来自nos的评论之后 - 我追踪了对该函数的特定调用,该函数现在经常导致此错误.

FileLog( "TimerRestore[%d], Name=%s", Package.CurGame->Timers[ Index ].Name.c_str() );
Run Code Online (Sandbox Code Playgroud)

我确实认为这可能会造成一些麻烦,因为"TimerRestore [%d],Name =%s"后面应该跟一个小数和字符串arguemtn,但是只给出一个字符串参数.我需要做一些测试,但我确定编写此代码的作者打算写:

FileLog( "TimerRestore[%d], Name=%s", Index, Package.CurGame->Timers[ Index ].Name.c_str() );
Run Code Online (Sandbox Code Playgroud)

但是我仍然不明白为什么函数调用似乎并不总是导致错误.或者也许是因为FileLog函数中的"ReEntrant"变量在没有失败的情况下会阻塞它?

非常感谢所有的反馈和信息.

Veg*_*ger 8

vprintf()(和朋友)允许使用va_list作为参数,这在函数具有可变数量的参数时很有用:

void log(FILE *file, const char* format, ... )
{
  va_list args;
  va_start (args, format);
  fprintf(file, "%s: ", getTimestamp());
  vfprintf (file, format, args);
  va_end (args);
}
Run Code Online (Sandbox Code Playgroud)

在您的应用程序中,您可以使用可变数量的参数调用此函数:

log(file, "i=%d\n", i);           // 3 arguments
log(file, "x=%d, y=%d\n", x, y);  // 4 arguments
Run Code Online (Sandbox Code Playgroud)

我不知道为什么你的函数会导致错误.您的代码段未提供足够的详细信息.提供的函数参数的类型数量可能是原因.