I have my own class that represents a custom string class. I'm using VS2012RC. I have overloaded some operators of my class CustomString.
Here's some code:
CustomString::CustomString(string setstr)
{
str = setstr;
}
CustomString::operator const char *()
{
return (this->str.c_str());
}
CustomString &CustomString::operator = (char *setstr)
{
str = setstr;
return *this;
}
I can define my object and use it like this:
CustomString str = "Test string";
and i can print the result as:
printf(str);
printf((string)(str).c_str());
printf((string)(str).data());
printf("%s\n",(string)(str).c_str());
printf("%s\n",(string)(str).data());
And there is not any error.
But if i use it like this:
printf("%s\n", str);
There is an exception in msvcr110d.dll (error in memory access)
Why printf(str) is ok, but printf("%s\n",str) is not ok?
How can i modify my code to use printf("%s\n",str) ?
...
After hours of googling, I found that explict cast (string), static_cast (str) and _str() method are add a null-terminated chars: '\0';
i've modified my code as:
printf("%s\n",str + '\0');
and it's worked!
Is there any way to modify my custom constructor to add a null-terminated string and pass a correct value with null-terminated chars to get working the following code:
printf("%s\n",str);
Don't use printf
, its more C-like than C++. Instead, use iostream
s, which provide a facility for you to format your own custom classes and send the to a file or stdout.
Here's a quick (untested) example that might work for you:
std::ostream& operator<< (std::ostream &os, const CustomString& str)
{
os << str.data();
return os;
}
and you'd print your custom string to stdout by doing something like
CustomString str;
// put some text in the custom string, then:
std::cout << str << std::endl;
You can't (at least not in a portable way). printf
looks at the object passed as parameter and treats it as a %s
, which is a char array. You run into undefined behavior. Also, the parameters passed to printf
are, sort of say, type-less.
Why printf(str) is ok?
Because the first parameter is types, and is a const char*
. The implicit cast is made via your operator. The rest of the parameters don't behave the same.
I'd use cout
instead, and overload operator << (ostream&, const CustomString&)
.
I said you can't, in a portable way. For a class like
class CustomString
{
char* str;
//...
};
that might work, because of how classes are represented in memory. But, again, it's still undefined behavior.
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