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

C++程序绘制地图后出现「╠」乱码字符的技术问询

解决Windows控制台C++地图绘制程序的乱码问题

问题根源分析

乱码出现的核心原因有两点:

  1. 字符数组初始化错误:
    • 原代码给每行的plane[i][width/dw]赋值'\n',但C语言字符串需要以'\0'作为终止符,缺少终止符会导致输出函数读取内存时越界,出现未知乱码。
    • 代码中plane[height / dh + 1][width / dw] = '\0';属于越界访问,因为plane数组只有height/dh行(索引范围0到height/dh-1),访问height/dh+1会破坏数组外的内存,引发不可预测的字符。
  2. 输出方式错误:
    • 原代码用puts(plane[0])只输出第一行,但puts会从起始地址一直读取到'\0',由于后续行没有终止符,会把所有行的内存连起来读取,最终读到非法内存区域的乱码。

修复步骤

  1. 修正数组初始化逻辑:
    • 初始化时给每行的最后一个位置(width/dw)赋值'\0',确保每行都是合法的C字符串。
    • 删除越界的数组赋值语句,避免内存污染。
  2. 逐行输出所有内容:
    • 循环遍历plane的每一行,用printf或cout逐行输出,替代只输出第一行的puts调用。
  3. 可选优化:
    • 添加Sleep控制刷新频率,避免控制台闪烁;或保留gotoxy(0,0)实现覆盖输出。

完整修正代码

#include <iostream>
#include <Windows.h>
#include <time.h>
#include <stdlib.h>
#include <cmath>
#include <cstdlib>

using namespace std;

//屏幕像素尺寸
const int width = 800, height = 600;

//每个控制台字符对应的像素尺寸
const int dw = 8, dh = 16;
//计算后控制台行列数:800/8=100列,600/16=37行(整数除法自动取整)

struct coord //存储角色坐标的结构体
{
    int x;
    int y;
};

void gotoxy(int x, int y) {
    HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD dwPos;
    dwPos.X = x;
    dwPos.Y = y;
    SetConsoleCursorPosition(hcon, dwPos);
}

void convert(int P[2], float x, float y) //将浮点坐标转换为控制台字符坐标
{
    P[0] = int(x) / dw;
    P[1] = int(y) / dh;
}

void convert(int P[2], int x, int y) //将整数坐标转换为控制台字符坐标
{
    P[0] = x / dw;
    P[1] = y / dh;
}

void drawpoint(char plane[height / dh][width / dw + 1], int A, int B, char C)//绘制单个字符到平面
{
    B = height / dh - 1 - B;
    if (A < 0 || B < 0 || A >= width / dw || B >= height / dh)  return;
    plane[B][A] = C;
}

class map
{
private:
    float n(float x)
    {
        return 0 ;
    }
public:
    float f(float x)
    {
        return (150 * (n(x) + 1.0f) / 2.0f); //返回地面高度对应的像素值
    }

    void draw(char plane[height / dh][width / dw + 1])
    {
        for (int i = 0; i < width / dw; i++)
        {
            int P[2];
            int j_start = static_cast<int>(f(i * dw)) / dh; //显式转换为整数,避免隐式截断歧义
            for (int j = j_start; j >= 0; j--)
            {
                convert(P, i * dw, j * dh);
                drawpoint(plane, P[0], P[1], 'o');
            }
            convert(P, i * dw, j_start * dh);
            drawpoint(plane, P[0], P[1], '#');
        }
    }
};

int main()
{
    map new_map;
    const int rows = height / dh;
    const int cols = width / dw;
    char plane[rows][cols + 1]; //每行cols+1个字符,最后一个存'\0'

    //初始化数组:每行填充'*',末尾加终止符
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            plane[i][j] = '*';
        }
        plane[i][cols] = '\0'; //每行末尾添加字符串终止符
    }

    while (true)
    {
        gotoxy(0, 0);
        //重置平面为全'*'
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                plane[i][j] = '*';
            }
        }
        new_map.draw(plane);
        //逐行输出所有内容
        for (int i = 0; i < rows; i++) {
            printf("%s\n", plane[i]);
        }
        Sleep(100); //添加小延迟,避免刷新过快
    }
    return 0;
}

额外说明

  • 修正了j_start的隐式类型转换问题,用static_cast<int>显式转换,避免浮点转整数的截断歧义。
  • 新增rows和cols常量,简化代码结构,减少重复计算。

内容的提问来源于stack exchange,提问作者jjuanda19

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:37:20