I haven't been able to find an answer to the following question, and I am having some issues related to the functions.
My main programming is done in C#, and never really learned C++ while studying, but in my current job I have to do some C++ programming aswell.
Most of the C++ programming have been done by a former employee, and he made a function for logging.
Once in a while this function results in an error (Access Violation) - this is not shown to the user, but I see it while running the code through debugger.
When the error happens it points to this line of code:
vfprintf( LogFile, fmt, va );
I then took a closer look at the code before and after, and to put the above into a context the code around is:
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;
}
Actually I dont understand why it is needed (and if it is?) call both fprintf and then vfprintf? I would think the first fprintf call would write the formatted string to the stream (File), and that would be enough?
A little explanation or some information would be much appreciated :)
EDIT: After the comment from nos - I tracked down the specific call to the function which today have often been causing this error.
FileLog( "TimerRestore[%d], Name=%s", Package.CurGame->Timers[ Index ].Name.c_str() );
I indeed think this could cause some trouble, as "TimerRestore[%d], Name=%s" should be followed by a decimal and string arguemtn, however only a string argument is given. I need to do some testing, but Im sure the author who wrote this code meant to write:
FileLog( "TimerRestore[%d], Name=%s", Index, Package.CurGame->Timers[ Index ].Name.c_str() );
However I still do not understand why the function call does not always seem to result in an error. Or maybe it is cause of the "ReEntrant" variable in FileLog function is blocking it when it does not fail?
Thanks a lot for all the feedback and information.
fprintf is used to output to stream. sprintf(buffer,...) is used to format a string to a buffer.
Definition and Usage. The vfprintf() function writes a formatted string to a specified output stream (example: file or database). Unlike fprintf(), the arguments in vfprintf(), are placed in an array.
printf function is used to print character stream of data on stdout console. fprintf: fprintf is used to print the string content in file but not on stdout console.
vprintf()
(and friends) allow to use va_list
as argument, which is useful when your function has a variable amount of arguments:
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);
}
In your application you can call this function with a variable amount of arguments:
log(file, "i=%d\n", i); // 3 arguments
log(file, "x=%d, y=%d\n", x, y); // 4 arguments
I do not know why your function results in an error. Your code snippet does not provide enough details. The amount of type of provided function arguments might be the cause.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With