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++ 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 << ", " <

然而,我经常遇到这样的错误:const char*类型的参数与char类型的参数不兼容*

我如何解决这个问题,使参数不再常数

我该如何解决这个问题

使用不同的方法,使用stringstream或辅助缓冲区

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的唯一原因是打印它,以便流操作符可以完美地工作。