使用C ++我试图为我的类实现一个toString()函数:
void ClassName::toString(string& returnString)
{
sprintf(returnString.c_str(), "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
}
但是我一直收到这个错误:类型为const char *的参数与char *类型的参数不兼容
如何修复此问题并使参数不再为常量?
答案 0 :(得分:5)
我该如何解决这个问题?
使用其他方法,改为使用stringstream
或辅助缓冲区。
void ClassName::toString(string& returnString)
{
std::stringstream ss;
ss << "Position: (" << position.x << ", " << position.y << ", "
<< position.z << ")\n");
returnString = ss.str();
}
并使参数不再是const?
不要。如果将c_str
更改为非const类型,地狱将会失败。同事们会哭泣。天使会失去翅膀。小猫会死。油价将上涨。股市崩盘。 Zombie apocalipse。
原因是const
- 所以你不要修改它。这样做会导致未定义的行为。
答案 1 :(得分:0)
在现代C ++中你可以说:
std::string ClassName::toString() const
{
return "Position: (" + std::to_string(position.x) + ", "
+ std::to_string(position.y) + ", "
+ std::to_string(position.z) + ")\n";
}
如果你必须使用printf
,你仍然可以使用字符串,但你必须先调整它的大小。
std::string ClassName::toString() const
{
static const int initial_size = 1024;
std::string s(initial_size);
int ret = std::snprintf(&s[0], s.size(), "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
s.resize(ret);
// handle overflow: print again
if (s.size() > initial_size)
{
std::snprintf(&s[0], s.size(), "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
}
return s;
}
请注意&s[0]
为您提供了一个指向可变char的指针,实际上是一个大小为s.size()
的整个数组的第一个元素。
答案 2 :(得分:0)
c_str()
返回const char *
,因为使用c_str()
函数返回的指针更改字符串的值通常不是一个好主意。
顺便说一句,你要做的事情毫无意义。您应该只使用returnString.append()
方法。
但是如果你必须使用sprintf,你应该确保你的字符串有空间来保存sprintf的输出。
第一种方法:您可以使用.reserve()
方法执行此操作,但如果直接修改字符串,则不会更改.size()
返回的字符串内部大小计数器使用sprintf()
方法的缓冲区(append()
将进行适当的大小调整)。如果您不需要使用.size()
方法,就不会有任何问题。
第二种方法(更好):如果您知道sprintf的确切输出长度,这是更好的方法。您应该使用.resize()
方法而不是.reserve()
。 .resize()
会正确调整字符串的大小计数器。
最后,您应该使用:sprintf(const_cast<char *>(returnString.data()), ...
顺便说一句,这件事并不是一个好主意。
<强> P.S。强>
.data()
与.**c**_str()
相同,除了它不附加null终止符以使其成为c样式字符串。
答案 3 :(得分:0)
为sprintf制作一个缓冲区。然后再分配给returnString。
void ClassName::toString(string& returnString)
{
char buffer[64] = {}; // expect the length of `Position Info` will not exceed 63
sprintf(buffer, "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
returnString = buffer;
}
答案 4 :(得分:-1)
http://www.cplusplus.com/reference/string/string/c_str/
返回的数组指向一个内部位置,该位置具有此字符序列所需的存储空间及其终止的空字符,但此数组中的值不应在程序中修改,只保证保持不变,直到接下来调用字符串对象的非常量成员函数。
您不得修改返回的char *
的内容尝试类似:
void ClassName::toString(string& returnString)
{
char tmp[256];
sprintf(tmp, "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
returnString=tmp;
}