C++ toString() with sprintf()
C++ toString() with sprintf()
有了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* 类型的参数不兼容
我如何解决这个问题并使参数不再恒定?
我该如何解决这个问题?
使用不同的方法,改用stringstream
或辅助缓冲区。
void ClassName::toString(string& returnString)
{
std::stringstream ss;
ss << "Position: (" << position.x << ", " << position.y << ", "
<< position.z << ")n");
returnString = ss.str();
}
并使论点不再持续?
不要。如果您将c_str
更改为非常量类型,地狱将中断。程序员同行会哭泣。天使将失去翅膀。小猫会死的。油价将上涨。股市崩盘。僵尸启示录。
它const
是有原因的 - 所以你不要修改它。这样做会导致未定义的行为。
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()), ...
顺便说一下,这整件事不是一个好主意。
附言 .data()
与 .**c**_str()
相同,只是它不附加 null 终止符以使其成为 C 样式字符串。
在现代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]
为您提供了一个指向可变字符的指针,实际上是指向大小为 s.size()
的整个数组中的第一个元素。
为 sprintf 创建一个缓冲区。然后分配给返回字符串返回。
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;
}
http://www.cplusplus.com/reference/string/string/c_str/
返回的数组指向一个内部位置,该位置具有此字符序列及其终止 null 字符所需的存储空间,但不应在程序中修改此数组中的值,并且仅保证在下次调用字符串对象的非常量成员函数之前保持不变。
您不得修改返回的字符的内容 *
尝试类似这样的操作:
void ClassName::toString(string& returnString)
{
char tmp[256];
sprintf(tmp, "Position: (%f, %f, %f)n", position.x, position.y, position.y);
returnString=tmp;
}
- Problems with std::cin.fail()
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 这对"With a stackless coroutine, only the top-level routine may be suspended."意味着什么
- 使用 sprintf 将十六进制0xAABBCC转换为字符串"AA:BB:CC"
- Boost.TEST with CLion: "Test framework quit unexpectedly"
- 避免碎片化的ClientHellos with OpenSSL (DTLS)
- Issues with Win32 ReadProcessMemory API
- 高精度双精度的 Sprintf 格式化问题
- Qt with WinAPI MouseProc
- [[maybe_unused]] with structured_binding?
- Issue with WriteProcessMemory
- OpenCV RTP-Stream with FFMPEG
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- std::adjacent_difference with std::chrono time_point
- sprintf(b, "%" ) 是否定义了?
- DLL Made with CMake 使程序崩溃
- QtCreator with C 库中的链接器问题
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- C++ toString() with sprintf()
- padding with sprintf