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

不清楚的 ANSI CUB/CUF 行为

如何解决不清楚的 ANSI CUB/CUF 行为

在研究 ANSI 控制序列时,我遇到了不清楚的行为。

我试图在终端中制作“矩阵”效果,其中 在一行 n 0/1 个数字中,每次循环迭代更改一个随机数字:

#include <iostream>
#include <chrono>
#include <thread>

const int n = 5; // row length
const int pause = 50; // milliseconds

int main() {
    using namespace std;
    using this_thread::sleep_for;
    using chrono::milliseconds;

    for (int i = 0; i < n; i++) {
      cout << rand() % 2;
    }

    int offset;
    while (true) {
      offset = rand() % n + 1; // random digit in row 1..n

      cout << "\x1b[" << offset << "D";
      cout.flush();
      sleep_for(milliseconds(pause));

      cout << rand() % 2;
      cout.flush();
      // cout << "\x1b[" << 1 << "D";
      // cout.flush();
      sleep_for(milliseconds(pause));

      cout << "\x1b[" << offset - 1 << "C";
      cout.flush();
      sleep_for(milliseconds(pause));
    }
}

据我所知,CSI offset D 将光标移回 offset 次(如果可能在当前行中),然后我 cout 随机数字,移动光标向前 1 次,然后我使用 CSI offset - 1 C 将其向前移动 offset - 1 次,这应该将光标返回到 n + 1行位置,所以 n 位在光标之前,但有时它比 n + 1 更远,因此,经过多次迭代后,它最终位于行的末尾。我想知道为什么会这样。

但是,当我使用 cout << "\x1b[" << 1 << "D"; 然后使用 cout << "\x1b[" << offset << "C"; 而不是 cout << "\x1b[" << offset - 1 << "C"; 时它工作正常。

我也知道使用 CSI n G,它也可以正常工作,但我想了解 CSI n C/D 发生了什么。也许是我的数学错误,但不使用 cout << "\x1b[" << 1 << "D"; 似乎等同于使用 cout << "\x1b[" << offset - 1 << "C";,所以我真的很困惑。

解决方法

似乎 \x1b[0C 将光标向右移动,至少在我的终端上是这样(不知道是否指定/要求行为)。

$ printf "a\x1b[0Cb\n"
a b
$ printf "a\x1b[1Cb\n"
a b

检查 offset - 1 是否不为零。

if (offset - 1) {
  cout << "\x1b[" << offset - 1 << "C";
}

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