微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 wchar_t 数组中添加换行符?

如何解决如何在 wchar_t 数组中添加换行符?

我正在开发一款主机游戏。它使用屏幕缓冲区在更新地图后刷新控制台窗口。

这是主要的 while 循环。

while (true) {
    //player.doStuff(_kbhit());
    //map.update();
    WriteConsoleOutputCharacter(
        console.getScreenBuffer(),(LPWSTR)map.getScreen(),map.getWidth() * map.getHeight(),{ 0,0 },console.getBytesWritten()
    );
    Sleep(1000 / 30);
}

在此循环之前,我从 .txt 文件获取地图布局:

class Map {
    int width,height;
    wchar_t* screen;
public:
    wchar_t* getScreen() {
        return screen;
    }
    void setScreen(std::string layoutFile,std::string levelDataFile) {
        std::ifstream levelData(levelDataFile);
        levelData >> width >> height;
        screen = new wchar_t[(width + 1) * height];
        levelData.close();

        std::wifstream layout(layoutFile);
        std::wstring line;

        for (int j = 0; j < height; j++) {
            std::getline<wchar_t>(layout,line);
            for(int i = 0; i < width; i++) {
                screen[j * width + i] = line.at(i);
            }
            screen[width * (j + 1)] = L'\n';
        }
        layout.close();
    }
};


map.setScreen("demo.txt","demo_data.txt");

问题是打印的地图显示一个没有任何换行符的字符串,如下所示:

00000__00000

当我希望它看起来像这样时:

0000
0__0 
0000

我尝试在每行写入后添加 L'\n'L'\r\n',但它不起作用。

解决方法

简而言之

这里有两个独立的问题:

  • 第一个是换行符被覆盖。
  • 第二个,一旦您更正了第一个,Windows 控制台 API 不处理换行符

更多详情

覆盖问题

我假设宽度不包括每行末尾的尾随换行符,因为您对屏幕的分配是:

new wchar_t[(width + 1) * height];   // real width is width + 1 for '\n'

现在查看您的逻辑,您添加到该行的最后一个 '\n' 设置为:

screen[ width * (j + 1) ]   // same as screen[ j * width + width ]

根据您的索引方案,这似乎没问题,因为您将布局字符复制到:

screen[ j * width + i ]`   // where `i` is between `0` and `width-1` 

因此换行符将位于 screen[ j * width + width ]

不幸的是,使用您的索引公式,下一行的第一个字符覆盖了相同的位置:将 j 替换为 j+1,将 i 替换为 0 给出:>

screen[ (j + 1) * width + 0 ]  

这是

screen[ (j + 1) * width ]    // same location as screen [ width * (j+1)]

尾随换行符的解决方案

更正您的索引方案,考虑到线的实际宽度是 width+1

所以索引公式变为:

    for(int i = 0; i < width; i++) {
        screen[j * (width+1) + i] = line.at(i);
    }

当然还有尾随的换行符:

    screen[j * (width+1) + width] = L'\n';  // self-explaining
    screen[(j+1) * (width+1) -1] = L'\n';   // or alternative 

控制台 API 的问题

WriteConsoleOutputCharacter() 没有真正支持换行符和控制字符。这些显示为问号。

文档提到了根据控制台模式处理这些控制字符的可能性,但我已经尝试过使用 Windows 10,甚至使用变体 WriteConsoleOutputCharacterA()(确保排除宽字符问题),它根本不起作用。

您有两种解决方案来完成这项工作,但这两种解决方案都需要一些返工:

  • 逐行显示输出并相应地控制光标位置
  • 使用 WriteConsoleOutput() 允许您指定目标矩形(高度和宽度)并在矩形中写入字符而无需换行。不幸的是,数组应该是 CHAR_INFO 而不是简单的字符。

第二种方式的例子:

std::string w = "SATORAREPOTENETOPERAROTAS";
SMALL_RECT sr{ 2,2,6,6 };
CHAR_INFO t[25];
for (int i = 0; i < 25; i++) { t[i].Char.AsciiChar = w[i]; t[i].Attributes = BACKGROUND_GREEN; }
WriteConsoleOutputA(
    hOut,t,{ 5,5 },{ 0,0 },&sr
);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?