I am trying to finalize my logging class. I have written it from scratch and do not wish to use an alternative library of any kind. My problem lies within the fact that my logger has trouble outputting std::strings and only works when I denote it with the string.c_str() function.
Here is my logfile output function:
void Log::writeSuccess(char * text,...)
{
// Grab the variables and insert them
va_list ap;
va_start(ap, text);
char buff[BUFFER_SIZE];
vsnprintf(buff, sizeof(buff), text, ap);
// Output to the log
logfile << "<-!-> " << buff << endl;
}
Here is a sample call to my log class object (ignore the uselessness of the call):
string test("This is a test string!");
errorLog.writeSuccess("Output: %s", test);
I end up with random characters and garbled output.
However, when I append the string, test with .c_str(), it outputs the text correctly.
The whole reason I am trying to avoid cstrings is because I understand they are not cross platform and am developing my client to support all the major operating systems.
To summarize:
-
What is wrong with my log output function? Do you see any way it could be improved?
-
Should I generally avoid c_strings?
You’re getting random garble when passing an
std::stringtovsnprintfbecause the format specifier"%s"is that of a C-string – achar*.std::stringis not of typechar*, butstd::string.c_str()is of typechar*.vsnprintfwill basically readchars pointed to by the address that it presumes is that of a start of a C-string, up until the NUL character'\0'.An
std::stringpushed onto the stack and passed as an argument tovsnprintfis not a pointer to achar, howevervsnprintfwill just treat these bytes as an address and start readingchars/bytes from this address, causing undefined behaviour.The
printffamily of functions are not typesafe, since they rely on a format string and variable argument list, which is why your code will compile but you’ll get unexpected results.Bottom line is the
printffamily of functions expect achar*when you use the format specifier"%s".I also think you’re confusing C style strings (
char[]) with the Microsoft-specificCStringclass. C style strings won’t cause you problems on different platforms at all; the literal"This is a test string!"is a C style string (const char[]).