仅清除控制台输出的一部分

时间:2013-02-25 08:44:57

标签: c++ windows visual-c++ console output

我想做什么:

光标最初在屏幕的左上角闪烁:

  

剩余160个字符
  _

当我按'i'时:

  

剩余159个字符

     

当我按'a'时:

  

剩下158个字符

     

IA

当我按'm'时:

  

剩下157个字符

     

IAM

等等。

需要做什么(据我所知):

  1. 只需要清除屏幕的前三个字符。
  2. 更新屏幕上新按下的键
  3. 我尝试了什么:

    我试图清除整个屏幕并写下之前的所有内容。

    为什么我对自己的所作所为不满意

    因为它会产生不稳定的外观。条目不顺畅。

    我需要您帮助我:

    一些内置功能或其他一些技术只能清除部分屏幕。

    我的规格:

    Windows XP SP 3

    IDE:Visual C ++ 2010 Express

3 个答案:

答案 0 :(得分:5)

首先要理解的是,C ++没有屏幕概念,作为语言的标准部分。标准输出可能是文件,打印机和cout不知道区别。

然而,屏幕“设备”本身通常更智能,并且识别一些命令。最广泛实施的是'\ r' - 回车和'\ n' - 换行。 '\ r'将光标移动到行的开头,'\ n'前进到下一行,但这不符合您的需要,就像您已经尝试过的那样。

这里似乎唯一的方法是使用curses(其中ncurses只是一个实现,尽管是Linux中的标准实现)。它为您提供了一个虚拟屏幕,其中包含各种命令以更新它们。然后它只采用更改的部分,并以优化的方式更新终端。

这只是使用ncurses的典型C程序的一个例子,值得一看:

#include <ncurses.h>

int main()
{   
    int ch;

    initscr();              /* Start curses mode        */
    raw();                  /* Line buffering disabled  */
    keypad(stdscr, TRUE);   /* We get F1, F2 etc..      */
    noecho();               /* Don't echo() while we do getch */

    printw("Type any character to see it in bold\n");
    ch = getch();           /* If raw() hadn't been called
                             * we have to press enter before it
                             * gets to the program      */

    printw("The pressed key is ");
    attron(A_BOLD);
    printw("%c", ch);
    attroff(A_BOLD);

    refresh();          /* Print it on to the real screen */
    getch();            /* Wait for user input */
    endwin();           /* End curses mode        */

    return 0;
}

printw()函数写入“虚构”屏幕。它将东西放入缓冲区并更新一些标志,并进行一些其他内部ncurses簿记。它实际上并没有向你的真实屏幕(控制台窗口)写任何东西。

您可以根据需要进行尽可能多的printw()写入,但是在您的程序执行其他操作以使“虚构”屏幕缓冲区内容转到真实屏幕之前,这些内容不会显示在真实屏幕上

导致从printw()缓冲区更新实际屏幕的一件事是refresh()(如上面的源代码示例所示)。

答案 1 :(得分:2)

Win32控制台不支持转义序列。您可以使用Console API

从控制台清除(0,0)前3个字符的小例子

#include <windows.h>

int main()
{
   HANDLE hOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);

   COORD coord = {0,0};
   ::SetConsoleCursorPosition(hOutput, coord);

   char buff[] = "   ";
   ::WriteConsoleA(hOutput, buff, 3, NULL, NULL);

   return 0;
}

如果您不喜欢Console API并希望使用ncurses类比,请参阅there

答案 2 :(得分:1)

如果您想管理整个屏幕,curses就是这样 去。否则,你可以使用转义序列做很多事情; 例如,请参阅http://en.wikipedia.org/wiki/ANSI_escape_code。 (从历史上看,这样的序列从一个终端到另一个终端不等 接下来,curses最初是一种解决这个问题的方法。 今天,ANSI转义码非常适用于控制台 窗口系统下的窗口,由Windows使用 控制台窗口和xterm。)

除了封装实际序列外,curses 支持面向字符的输入,有或没有回声。这个 没有诅咒就更难做到,而且仍然非常 不可移植。