Search code examples
printfstringc++builder-6

Why is empty string transformed to "(null)"?


I have following code sample:

double t_values[FFT_SIZE];
AnsiString prefix;
double multiplier;
AutoScaleData(t_values, FFT_SIZE, prefix, multiplier);

AnsiString str;
str.printf("Voltage [%sV]", prefix);

Pretty simple isn't it? String str is used as description for numeric values displayed in graph. For value say 0.05 V it is much more comprehensive and intuitive to say instead that "voltage is 50 mV". This is ensured through using proper prefix in this case "m". For values range <1; 1000) there is no need to add any prefix. We can for example say "voltage over this element is 50 volts" and this is perfectly understandable. I have problem that library function printf keeps adding string "(null)" when prefix is empty string for example:

"Voltage [(null)V]"

I haven't seen this type of behaviour anytime before when using Microsoft Visual Studio. Can this behaviour be somehow avoided?


Solution

  • Short Answer:

    str.printf("Voltage [%sV]", prefix.c_str());
    

    Detailed Answer:

    AnsiString contains a single class member, a char* pointer named Data. When the string is empty, the Data pointer is NULL. The Data pointer resides at the starting memory address of the AnsiString instance.

    When calling printf(), its %s specifier is expecting you to pass in a char* pointer, but you are passing in an AnsiString instance instead. That is effectively the same as passing printf() the internal AnsiString::Data pointer directly. In other words, this statement:

    str.printf("Voltage [%sV]", prefix);
    

    Is effectively the same as if you had done this instead:

    str.printf("Voltage [%sV]", prefix.data());
    

    That is why printf() outputs "(null)". You are passing it a NULL pointer to begin with.

    The AnsiString::c_str() method never returns a NULL pointer. If the string is not empty, c_str() returns the AnsiString::Data pointer as-is. Otherwise, it returns a pointer to a static '\0' character instead. Either way, printf() does not receive a NULL pointer in that situation. If the string is empty, it receives a pointer to a 0-length null-terminated string, so it outputs a blank string instead of "(null)".