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?

a simple null check is too complicated compared to the trusting default behaviours of the compilers? get serious.
–
Emir AkaydınDec 8 '11 at 13:05

1

prefix is not a pointer, so you cannot compare it to NULL directly. prefix is a class, so you would be passing NULL to the class's != operator, which expects another instance of the class. The class in question is an AnsiString, which has constructors for both int and char*. Passing a NULL to an AnsiString constructor will interpret is as an int, not a char*, so you would effectively be doing a prefix != "0" comparison instead.
–
Remy LebeauDec 8 '11 at 22:18

4 Answers
4

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)".

as mentioned by Remy Lebeau, prefix == NULL doesn't work as you'd expect because of AnsiString's overloading, prefix == NULL is effectively the same as prefix == "0".. if you want to do it this way, you can do str.printf("Voltage [%sV]", prefix.IsEmpty() ? "" : prefix); .. but really, just use c_str()
–
Afriza N AriefMay 12 at 4:02

What type is prefix? Very good information to have had in the question.
–
Joachim PileborgDec 8 '11 at 13:03

Thank you for your remark. I added it to question.
–
truthseekerDec 8 '11 at 13:10

I'm guessing that prefix is of type std::string? The printf-style functions, when passed "%s" expected a char * or char [] type. The std::string class do not convert to any of those types, so printf will print something else, and it can event crash. The std::string::c_str() function returns a const char * type string, which can be used by the old-fashioned printf-styled functions.
–
Joachim PileborgDec 8 '11 at 13:12