【问题标题】:C - Remove a newline character that has already been printedC - 删除已打印的换行符
【发布时间】:2014-07-26 03:31:01
【问题描述】:

如何删除已打印并加载到缓冲区中的换行符?据我所知,\b 字符仅将光标移回当前行,并且不适用于换行符。我该如何解决这个问题?

如果对问题进行编辑以表明这个不受欢迎的换行符是如何发出的,那将会很有帮助。 – Mahonri Moriancumer

这其实不是不可取的。我想在输出另一种状态之前用缓冲区的一种状态预览用户。但是,我不想连续显示多个缓冲区状态。例如,假设我要显示两个矩阵,

1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

我希望第二个矩阵替换第一个。为此,我需要删除第一个矩阵的输出数字。

也许您可能会考虑再次编辑您的问题并指出操作系统和/或终端类型?

当前运行 Linux (Ubuntu) x64,使用 xterm(确切地说是 ROXTerm)。

【问题讨论】:

  • 在缓冲区的第 (last-1) 个索引中添加 /0 字符,可能会有所帮助
  • 您可以找到换行符的位置(参见strstr(s, "\n"))并截断字符串(在行尾放置'\0'(而不是'\n'))
  • 如果对问题进行编辑以指示此不受欢迎的换行符是如何发出的,将会很有帮助。
  • 您说的是stdout 缓冲区,还是您自己制作的内存缓冲区?如果是前者,你会得到的建议是“不要那样做”。
  • @user3386109 这是一个stdout 缓冲区。

标签: c linux newline backspace


【解决方案1】:

有两个广泛支持的字符用于覆盖之前编写的内容:\b,退格,正如您提到的,和 \r,回车,将“写头”带回到开头行。

如果你想回到上一行,你也完全不走运,但你必须求助于一些仍然得到广泛支持的东西,尤其是终端模拟器, 可能没有得到如此广泛的支持(例如,如果您将它通过管道传输到 lp,它可能不会起作用)。我指的是 ANSI 转义序列。有很多,但需要注意的是^[[A,它将“写头”向上移动一行。 (^[ 这里是ESC ASCII 字符,十六进制值0x1B)。在 C 中使用它:

printf("\x1B[A");  /* move up one line */

【讨论】:

  • 或者,向上移动 4 行,\x1B[4A。 (见:invisible-island.net/xterm/ctlseqs/ctlseqs.html 即:CSI P s A
  • 如果我想编辑上一行的结尾(例如"Hello\n" "\x1B[A" "\b "),您给出的答案将不起作用。尽管如此,它还是按照我的要求做到了。为此,我感谢您,先生。
【解决方案2】:

此问题的解决方案取决于您使用的输出设备类型和系统。听起来您正在使用控制台。如果您使用的是 Unix 变体,则可以使用 curses 库来控制屏幕并将文本放置在您想要的位置。

您面临的问题是 \n 是 C 构造。在某些时候,系统会将 \n 转换为用于控制台显示的序列。

【讨论】:

    【解决方案3】:

    我发布此内容是为了帮助从谷歌来到这里的任何人。

    您可以使用 ANSI 转义序列 \x1B[s 将光标位置保存在要覆盖的行的末尾,然后使用 \x1B[u\x1B[<number of lines to move up>A 将光标放回换行符之前的位置。

    这是一个在用户按下回车后覆盖上一行的工作示例:

    #include <stdio.h>
    
    int main() {
      char user_input[2];
    
      printf("Press enter to see a magic trick -> \x1B[s");
      fgets(user_input, 2, stdin); //press enter to continue
      
      printf("\x1B[u\x1B[ATa-da!\n\nLook at line 1!\n");
      fflush(stdout); //flush output to console immediately
      return 0;
    }
    

    需要注意的是,并非所有终端都支持所有 ANSI 转义序列。您可以使用man 5 terminfo 查看终端的功能。

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 2012-04-14
      • 2011-03-09
      • 1970-01-01
      • 2012-10-07
      相关资源
      最近更新 更多