【问题标题】:Extra Spaces Being Added After Clear Screen清除屏幕后添加的额外空间
【发布时间】:2015-12-27 17:05:29
【问题描述】:

我有以下代码:

#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>

#define RESET "\x1b[1J"

#define D "\x1b[0m"
#define Y "\x1b[33;1m"
#define W "\x1b[37;1m"
#define B "\x1b[30;1m"

void printLeft(bool color)
{
  if (color) {
    printf(Y "               __\n"
           "              /  |\n"
           "             /   \\\n"
           "            /     |\n"
           W "      _\\|  " Y "|" W "[" B "*" W "][" B "*" W "]" Y "|  " W "|/_\n"
           "        \\  " Y "|      |  " W "/\n"
           "         --" Y "|" W "\\____/" Y "|" W "--\n"
           Y "           \\      |\n"
           "            \\     /\n"
           "             \\   |\n"
           W "             |" Y "\\__|" W "|\n"
           "             |    |\n"
           "           ==|    |==");
  } else {
    printf("               __\n"
           "              /  |\n"
           "             /   \\\n"
           "            /     |\n"
           "      _\\|  |[*][*]|  |/_\n"
           "        \\  |      |  /\n"
           "         --|\\____/|--\n"
           "           \\      |\n"
           "            \\     /\n"
           "             \\   |\n"
           "             |\\__||\n"
           "             |    |\n"
           "           ==|    |==");
  }
}

void printRight(bool color) {
  if (color) {
    printf(Y "               __\n"
           "              |  \\\n"
           "              /   \\\n"
           "             |     \\\n"
           W "        _\\|  " Y "|" W "[" B "*" W "][" B "*" W "]" Y "|  " W "|/_\n"
           "          \\  " Y "|      |  " W "/\n"
           "           --" Y "|" W "\\____/" Y "|" W "--\n"
           Y "             |      /\n"
           "             \\     /\n"
           "              |   /\n"
           W "             |" Y "|__/" W "|\n"
           "             |    |\n"
           "           ==|    |==");
  } else {
    printf("               __\n"
           "              |  \\\n"
           "              /   \\\n"
           "             |     \\\n"
           "        _\\|  |[*][*]|  |/_\n"
           "          \\  |      |  /\n"
           "           --|\\____/|--\n"
           "             |      /\n"
           "             \\     /\n"
           "              |   /\n"
           "             ||__/|\n"
           "             |    |\n"
           "           ==|    |==");
  }
}

void printBottom(bool color) {
  if (color) {
    printf(Y "               __\n"
           "              |  |\n"
           "             /    \\\n"
           "            |      |\n"
           "            |" W "[" B "*" W "][" B "*" W "]" Y"|\n"
           "            |      |\n"
           W "        _\\| " Y "|" W "\\____/" Y "| " W "|/_\n"
           "          \\/" Y "|      |" W "\\/\n"
           Y "            |      |\n"
           W "           /\\" Y "\\    /" W "/\\\n"
           "        ==/   " Y "|__|   " W "\\==");
  } else {
    printf("               __\n"
           "              |  |\n"
           "             /    \\\n"
           "            |      |\n"
           "            |[*][*]|\n"
           "            |      |\n"
           "        _\\| |\\____/| |/_\n"
           "          \\/|      |\\/\n"
           "            |      |\n"
           "           /\\\\    //\\\n"
           "        ==/   |__|   \\==");
  }
}

int main(int argc, char *argv[])
{
  short counter = 0;
  while (1) {
    printf(RESET);
    if (counter == 0) printLeft(true);
    else if (counter == 2) printRight(true);
    else printBottom(true);
    if (true) {
      printf(Y "\n\n\"IT'S PEANUT BUTTER JELLY TIME\"" D);
    } else {
      printf("\n\n\"IT'S PEANUT BUTTER JELLY TIME\"");
    }
    fflush(stdout);
    usleep(200000);
    counter = (counter + 1) % 4;
  }
  return 0;
}

除了一件事,一切都很好。第一行似乎添加了额外的空间:

我怎样才能摆脱这个多余的空间?

【问题讨论】:

  • 是不是因为这里的逻辑错误:if (true) {...} else {...}导致总是输出第一个输出文本?
  • @WeatherVane 对于每种方法,是的,将输出颜色版本。我稍后会添加一个标志来切换颜色或不颜色。
  • 发布的代码缺少 stdio.h 和 unistd.h 和 stdbool.h 的 #include 语句 RESET 没有定义。

标签: c ansi-escape


【解决方案1】:

虽然我无法在我的系统上使用控制代码进行测试,但您很可能需要在此文本后添加 \n

printf(Y "\n\n\"IT'S PEANUT BUTTER JELLY TIME\"\n" D);

至少,这在 Windows 系统上解决了同样的问题(YD 似乎是颜色控制代码,所以这不应该影响位置)。

更新

似乎position control code 也存在(虽然不能在这里测试):

#define     GOTOYX   "\x1B[%.2d;%.2dH"
    Set cursor to (y, x). More...

因此您可以使用此代码来定位您的第一行而不是额外的换行符。

【讨论】:

  • 这确实有效,但它确实在底部添加了一个额外的换行符,我猜这不是世界末日。谢谢!
  • 也许您可以检查一下何时添加换行符,何时不添加?但是您是否也没有可用于位置的控制代码?那可能会更好。
  • 是的。我想我已经想通了。也许\x1b[1J 保留光标位置(我认为它会重置它)。我会找到一个控制代码来解决这个问题。谢谢你的帮助! :)
【解决方案2】:

尝试在第一行之前插入一个\n 字符。

【讨论】:

  • 它会缓慢地向下移动屏幕,但之后确实有效。
【解决方案3】:

我在使用 gcc 编译的 ubuntu linux 14.04。

以下代码干净地编译并执行所需的操作。

我无法让\1b[2j(清屏)工作,发现我不需要它。

一些重大变化是

  1. 每个图形的最后一行以\n 结束,所以最后一行总是立即输出
  2. 将图形修改为相同的宽度和高度
  3. 修改了if(true) 语句以在彩色和纯文本输出之间交替
  4. 删除了对fflush()的不必要调用
  5. 图形第一行偏移错误的原因是没有使用正确的间距来允许图形中一行开头的w,并且没有输出整个图形输出并且没有制作所有图形相同的高度/宽度。

以下代码是结果

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>

#define D "\x1b[0m"
#define Y "\x1b[33;1m"
#define W "\x1b[37;1m"
#define B "\x1b[30;1m"
#define CURSOR_1_1 "\x1b[1;1f \n"

void printLeft(bool color)
{
  if (color) {
    printf(CURSOR_1_1
           Y
           "               __                               \n"
           "              /  |                              \n"
           "             /   \\                             \n"
           "            /     |                             \n"
           W
           "      _\\|  " Y "|" W "[" B "*" W "][" B "*" W "]" Y "|  " W "|/_\n"
           "        \\  " Y "|      |  " W "/               \n"
           "         --" Y "|" W "\\____/" Y "|" W "--      \n"
           Y
           "           \\      |                            \n"
           "            \\     /                            \n"
           "             \\   |                             \n"
           W
           "             |" Y "\\__|" W "|                  \n"
           "             |    |                             \n"
           "           ==|    |=                            \n");
  } else {
    printf(CURSOR_1_1
           "               __                               \n"
           "              /  |                              \n"
           "             /   \\                             \n"
           "            /     |                             \n"
           "      _\\|  |[*][*]|  |/_                       \n"
           "        \\  |      |  /                         \n"
           "         --|\\____/|--                          \n"
           "           \\      |                            \n"
           "            \\     /                            \n"
           "             \\   |                             \n"
           "             |\\__||                            \n"
           "             |    |                             \n"
           "           ==|    |==                           \n");
  }
}

void printRight(bool color) {
  if (color) {
    printf(CURSOR_1_1
           Y
           "               __                               \n"
           "              |  \\                             \n"
           "              /   \\                            \n"
           "             |     \\                           \n"
           W
           "        _\\|  " Y "|" W "[" B "*" W "][" B "*" W "]" Y "|  " W "|/_        \n"
           "          \\  " Y "|      |  " W "/             \n"
           "           --" Y "|" W "\\____/" Y "|" W "--    \n"
           Y
           "             |      /                           \n"
           "             \\     /                           \n"
           "              |   /                             \n"
           W
           "             |" Y "|__/" W "|                   \n"
           "             |    |                             \n"
           "           ==|    |==                           \n");
  } else {
    printf(CURSOR_1_1
           "               __                               \n"
           "              |  \\                             \n"
           "              /   \\                            \n"
           "             |     \\                           \n"
           "        _\\|  |[*][*]|  |/_                     \n"
           "          \\  |      |  /                       \n"
           "           --|\\____/|--                        \n"
           "             |      /                           \n"
           "             \\     /                           \n"
           "              |   /                             \n"
           "             ||__/|                             \n"
           "             |    |                             \n"
           "           ==|    |==                           \n");
  }
}

void printBottom(bool color) {
  if (color) {
    printf(CURSOR_1_1
           Y
           "               __                               \n"
           "              |  |                              \n"
           "             /    \\                            \n"
           "            |      |                            \n"
           "            |" W "[" B "*" W "][" B "*" W "]" Y"|         \n"
           "            |      |                            \n"
           W
           "        _\\| " Y "|" W "\\____/" Y "| " W "|/_  \n"
           "          \\/" Y "|      |" W "\\/              \n"
           Y
           "            |      |                            \n"
           W
           "           /\\" Y "\\    /" W "/\\              \n"
           "        ==/   " Y "|__|   " W "\\==             \n"
           "                                                \n"
           "                                                \n");
  } else {
    printf(CURSOR_1_1
           "               __                               \n"
           "              |  |                              \n"
           "             /    \\                            \n"
           "            |      |                            \n"
           "            |[*][*]|                            \n"
           "            |      |                            \n"
           "        _\\| |\\____/| |/_                      \n"
           "          \\/|      |\\/                        \n"
           "            |      |                            \n"
           "           /\\\\    //\\                        \n"
           "        ==/   |__|   \\==                       \n"
           "                                                \n"
           "                                                \n");
  }
}

int main( void )
{
    int counter = 0;
    printf(CURSOR_1_1);
    while (1)
    {
        if (counter == 0) printLeft(true);
        else if (counter == 2) printRight(true);
        else printBottom(true);

        if (counter&0x01)
        {
          printf(Y "\n\n\"IT'S PEANUT BUTTER JELLY TIME\"%s\n", D );
        }

        else
        {
          printf("\n\n\"IT'S PEANUT BUTTER JELLY TIME\"\n");
        }
        //fflush(stdout);
        usleep(200000);
        counter = (counter + 1) % 4;
    }
    return 0;
}

【讨论】: