C++ StoScript()与SpIFTFF() C++,我尝试为我的类实现一个toStand函数: void ClassName::toString(string& returnString) { sprintf(returnString.c_str(), "Position: (%f, %f, %f)\n", position.x, position.y, position.y); }
然而,我经常遇到这样的错误:const char*类型的参数与char类型的参数不兼容* 我如何解决这个问题,使参数不再常数 我该如何解决这个问题 使用不同的方法,使用stringstream或辅助缓冲区C++ StoScript()与SpIFTFF() C++,我尝试为我的类实现一个toStand函数: void ClassName::toString(string& returnString) { sprintf(returnString.c_str(), "Position: (%f, %f, %f)\n", position.x, position.y, position.y); },c++,string,tostring,printf,c-str,C++,String,Tostring,Printf,C Str,然而,我经常遇到这样的错误:const char*类型的参数与char类型的参数不兼容* 我如何解决这个问题,使参数不再常数 我该如何解决这个问题 使用不同的方法,使用stringstream或辅助缓冲区 void ClassName::toString(string& returnString) { std::stringstream ss; ss << "Position: (" << position.x << ", " <
void ClassName::toString(string& returnString)
{
std::stringstream ss;
ss << "Position: (" << position.x << ", " << position.y << ", "
<< position.z << ")\n");
returnString = ss.str();
}
让论点不再是常数
不要。如果你把c_str改成非常量类型,那你就输定了。其他程序员会哭泣。天使会失去翅膀。小猫会死的。油价将上涨。股市崩盘。僵尸世界末日
它是常量是有原因的,所以您不需要修改它。这样做将导致未定义的行为
我该如何解决这个问题
使用不同的方法,使用stringstream或辅助缓冲区
void ClassName::toString(string& returnString)
{
std::stringstream ss;
ss << "Position: (" << position.x << ", " << position.y << ", "
<< position.z << ")\n");
returnString = ss.str();
}
让论点不再是常数
不要。如果你把c_str改成非常量类型,那你就输定了。其他程序员会哭泣。天使会失去翅膀。小猫会死的。油价将上涨。股市崩盘。僵尸世界末日
它是常量是有原因的,所以您不需要修改它。这样做将导致未定义的行为
返回的数组指向一个内部位置,该位置具有该字符序列所需的存储空间及其终止的空字符,但该数组中的值不应在程序中修改,并且只能保证在下次调用string对象的非常量成员函数之前保持不变
不允许修改返回的字符的内容*
尝试以下方法:
void ClassName::toString(string& returnString)
{
char tmp[256];
sprintf(tmp, "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
returnString=tmp;
}
返回的数组指向一个内部位置,该位置具有该字符序列所需的存储空间及其终止的空字符,但该数组中的值不应在程序中修改,并且只能保证在下次调用string对象的非常量成员函数之前保持不变
不允许修改返回的字符的内容*
尝试以下方法:
void ClassName::toString(string& returnString)
{
char tmp[256];
sprintf(tmp, "Position: (%f, %f, %f)\n", position.x, position.y, position.y);
returnString=tmp;
}
在现代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)给出了一个指向可变字符的指针,实际上,对于C++中的大小S.Sig../P>< P>数组的第一个元素,可以说:
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]为您提供了一个指向可变字符的指针,实际上是指向大小为s.size的整个数组的第一个元素。c_str返回一个常量字符*,因为使用c_str函数返回的指针更改字符串的值通常不是一个好主意
顺便说一句,你想做的是毫无意义的。您应该只使用returnString.append方法
但是,如果必须使用sprintf,则应该确保字符串有足够的空间容纳sprintf的输出
第一个方法:您可以使用.reserve方法进行操作,但它不会更改字符串的内部大小计数器,该计数器由.size返回。如果您直接使用sprintf方法修改字符串缓冲区,append将进行适当的大小调整。据我所知,如果您不需要使用.size方法,就不会有任何问题
第二种更好的方法:如果您知道sprintf的确切输出长度,那么这是更好的方法。您应该调用.resize方法,而不是.reserve。调整大小将正确调整字符串的大小计数器
最后,您应该使用:sprintfconst_castreturnString.data
顺便说一句,这整件事不是个好主意
附言。
.data与。**c**u str相同,只是它没有附加null终止符以使其成为c样式的字符串。c_str返回一个常量字符*,因为使用c_str函数返回的指针更改字符串的值通常不是一个好主意
顺便说一句,你想做的是毫无意义的。您应该只使用returnString.append方法
但是,如果必须使用sprintf,则应该确保字符串有足够的空间容纳sprintf的输出
第一个方法:您可以使用.reserve方法进行操作,但它不会更改字符串的内部大小计数器,该计数器由.size返回。如果您直接使用sprintf方法修改字符串缓冲区,append将进行适当的大小调整。据我所知,如果您不需要使用.size方法,就不会有任何问题
第二种更好的方法:如果您知道sprintf的确切输出长度,那么这是更好的方法。您应该调用.resize方法,而不是.reserve。调整大小将正确调整字符串的大小计数器
最后,您应该使用:sprintfconst_castreturnString.data
顺便说一句,这整件事不是个好主意
附言。
.data与。**c**u str相同,只是它没有附加null终止符以使其成为c-s
tyle字符串。为sprintf创建一个缓冲区。然后分配给returnString back
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;
}
为sprintf创建一个缓冲区。然后分配给returnString back
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;
}
地狱会打破失去它啊。不需要一根绳子。只需为类定义一个流操作符。如果您确实需要字符串,那么您可以使用lexial_cast进行转换,但通常使用toString的唯一原因是打印它,这样流操作符就可以完美地工作。地狱会打破它,失去它!:啊。不需要一根绳子。只需为类定义一个流操作符。如果您确实需要一个字符串,那么您可以使用lexial_cast来进行转换,但通常使用toString的唯一原因是打印它,以便流操作符可以完美地工作。