SDL2开发中int转char渲染FPS计数时末尾出现乱码如何解决
SDL2 FPS计数器整数转字符数组显示乱码问题
问题描述
我正在使用SDL2开发游戏,计划添加每秒更新数值的FPS计数器功能,当前实现代码如下:
bool updateFPS() { if (fpsDTime == 1) { // 距上次更新间隔满1秒 frameCounterS++; // 累加当前帧 fpsTime = currentTime; // 重置计时器 // 尝试将int类型转为char数组用于显示 char SframeCounterS[MAX_DIGITS + sizeof(char)]; std::to_chars(SframeCounterS, SframeCounterS + MAX_DIGITS, frameCounterS); // 文本渲染逻辑 message = TTF_RenderText_Blended(HPusab, SframeCounterS, White); // 加载文本到渲染变量 std::cout << SframeCounterS << std::endl; // 控制台调试输出 if (message == NULL) { std::cout << "Could not create message! " << SDL_GetError() << std::endl; return false; } // 错误校验 slotEight = SDL_CreateTextureFromSurface(gRenderer, message); // 从表面创建纹理 if (slotEight == NULL) { std::cout << "Could not create Message! " << SDL_GetError() << std::endl; return false; } // 纹理创建错误校验 rslotEight.x = 30; // 矩形X坐标 rslotEight.y = 10; // 矩形Y坐标 rslotEight.w = message->w; // 矩形宽度 rslotEight.h = message->h; // 矩形高度 frameCounterS = 0; // 重置FPS帧计数 }
我选择将int转为char数组而不是std::string,是因为TTF_RenderText接口要求传入char*类型作为文本输入参数。目前代码可以正常显示FPS数值,但数字末尾会附带大量乱码字符。
控制台调试输出效果:
求问当前int转char数组的实现缺少什么操作,才能实现无乱码的正常显示?
问题原因与修复方案
乱码的核心原因是C风格字符串要求必须以\0(空终止符)结尾,而std::to_chars在转换完成后不会自动在写入的数字末尾添加空终止符。无论是cout输出还是TTF_RenderText读取字符串,都会一直向后读取内存直到遇到随机出现的\0才会停止,这部分越界读取的内存内容就会显示为乱码。
std::to_chars的返回值是to_chars_result结构体,其中的ptr成员会指向转换完成后写入的最后一个字符的下一个位置,你只需要在这个位置手动写入\0即可解决问题。
修复后的转换代码
// 数组大小只需要多留1字节存终止符即可,sizeof(char)固定为1,不需要额外计算 char SframeCounterS[MAX_DIGITS + 1]; auto convertRes = std::to_chars(SframeCounterS, SframeCounterS + MAX_DIGITS, frameCounterS); if (convertRes.ec == std::errc()) { // 校验转换是否成功,避免数值超出数组容量 *convertRes.ptr = '\0'; // 手动添加空终止符 } else { // 转换失败的兜底逻辑 strcpy(SframeCounterS, "ERR"); }
更简洁的可选方案
你完全可以用std::string存储转换结果,不需要手动维护char数组,调用c_str()方法就能直接传入TTF_RenderText_Blended,接口完全兼容,也不会出现空终止符相关的错误:
std::string fpsStr = std::to_string(frameCounterS); message = TTF_RenderText_Blended(HPusab, fpsStr.c_str(), White);
内容的提问来源于stack exchange,提问作者Manifest
相关产品推荐
相关产品推荐

