You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:18:32