光标定位函数 gotoxy()与清屏函数clrscr()

在网上很多用C语言编写的趣味小游戏程序中,用到了 gotoxy() 和 clrscr() 这两个函数。但是当代的编程初学者常常会发现,编译通不过,出错信息是找不到这两个函数。在此解释其原因,并提供解决方案。

历史原因

在上世纪80-90年代,DOS 操作系统大行其道(Windows系统尚未开发并广泛使用),由 Borland (宝兰德)公司开发的用于编写 C 或 C++ 程序的集成开发环境 Turbo C (后来改名叫 Borland C++)非常流行。这个集成开发环境中除了包含 C 和C++ 标准函数库之外,还包含了该公司自行开发的一个控制终端窗口屏幕输入和输出的扩充函数库,各个函数的原型在头文件“conio.h”中声明。该头文件的名称来源于英语“console input /output”,意为“终端窗口输入输出”。

因此,只要在自己的程序中用 #include 命令包含该头文件,即在程序前面部分写上如下代码行:

#include <conio.h>

就可使用该函数库中的各个函数。

该函数库中的函数在编写趣味小游戏程序时非常有用,所以得到了广泛的应用。现在流传下来的很多趣味小游戏程序中就用到了其中的函数,最常用的就是 gotoxy 函数和 clrscr 函数。

但是,时至今日,Windows 系统已经得到了广泛使用,运行于 DOS 系统上的 Turbo C(Borland C++)并没有合适的 Windows 升级版本。当代流行的 C 或 C++ 集成开发环境是 微软公司的 Visual C++ 或 免费的 Dev-C++、Code::Blocks(其中使用了免费的 GCC编译器),在这些集成开发环境中并不包括 Borland 公司的扩充函数库 conio,所以如果在程序中使用 gotoxy 函数或 clrscr 函数,就会编译出错。

如果您安装使用本文作者改进发布的“小龙Dev-C++” (主页: devcpp.gitee.io ),那么很高兴地告诉您:小龙Dev-C++ 已经通过内部技术方法来支持这些函数了!只要在程序头部写上“#include <conio.h>”,那么就可以在程序中使用这些函数了,而不必按照下文所述的方法自行编写这些函数。

如果您不是使用小龙Dev-C++,就需要在自己的程序中想办法代替原有的这些函数。

gotoxy 函数

gotoxy(int x, int y) 是 Borland C 扩充函数库 conio.h 中声明的一个函数,功能是将 光标 移动到屏幕指定位置。在屏幕的左上角被定义为光标的坐标原点 (0, 0),横向为 X 轴,纵向为 Y 轴。

函数原型声明 : void gotoxy(int x, int y);

用法 :gotoxy(x, y) 将光标移动到指定列坐标 x 和行坐标 y。设置光标到文本屏幕的指定位置,其中参数 x,y 为文本屏幕的坐标。gotoxy(0,0)将光标移动到屏幕左上角。

如果在 Turbo C 或 Borland C++ 中使用 gotoxy 函数,就需要在文件头部添加如下代码行,以包含头文件 conio.h:

#include <conio.h>

由于它不是一个 C 和 C++ 标准函数库中的函数,在当代的其它编译器(例如 Visual C++ 或 GCC)中并没有提供这个函数(例如 Dev-C++ 、Code::Blocks和 C-Free 都是使用 GCC编译器)。不过可以利用 Windows 提供的API( 应用程序接口 )函数自定义这个函数 [1] 。下面是一个简洁的版本:

void gotoxy(short x, short y) {
 COORD coord = {x, y}; 
 //COORD是Windows API中定义的一种结构体类型,表示控制台屏幕上的坐标。
 //上面语句是定义了COORD类型的变量coord,并以形参x和y进行初始化。
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
 //GetStdHandle(STD_OUTPUT_HANDLE); 获取控制台输出句柄
 //然后用SetConsoleCursorPosition设置控制台(cmd)光标位置

注意,在上面代码中使用了Windows 的 API 函数,所以需要在程序中包含头文件 windows.h:

#include <windows.h>

要想在 Visual C++ 或 GCC 中使用 gotoxy 函数,就需要把上面自定义的 gotoxy 函数写在自己的程序中。

举例:下面这个 C 程序将在屏幕中第5行10列(横向为X,纵向为Y轴)中央输出“hello world”

#include <stdio.h>
#include <windows.h>
void gotoxy(short x, short y) {
  COORD coord = {x, y};
  SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
int main(void) { 
  gotoxy(10, 5);
  printf("Hello world\n");
  return 0;
} 

clrscr 函数

clrscr()函数是 Borland C 扩充函数库 conio.h 中声明的一个函数,名称是英语“clear screen”的缩写,功能是清除文本模式的控制台窗口(简称清屏)。在当代的 Visual C++ 或 GCC 中可以使用命令 system("cls") 代替它,或者自定义这个函数。

功能与定义

在上世纪80-90年代流行的集成开发环境 Turbo C 或 Borland C 中的扩充函数库 conio.h 提供了 clrscr() 函数,(是“clear screen”的缩写),功能是清除文本模式的控制台窗口(简称清屏)。

函数原型声明: void clrscr(void);

用法:clrscr() 清空当前的控制台窗口,并将光标移动到屏幕左上角 (0, 0) 处。

由于它不是一个 C 和 C++ 标准函数库中的函数,在当代的其它编译器(例如 Visual C++ 或 GCC)中并没有提供这个函数(例如 Dev-C++ 、Code::Blocks和 C-Free 都是使用 GCC编译器)。有两种替代解决方案:

方法1 :使用 system () 函数调用控制台窗口中的 cls (清屏)命令:

 system("cls");

需要注意的是,在程序中使用 system() 函数时,需要包含头文件 stdlib.h,即在程序头部写如下代码行:

#include <stdlib.h>

这种办法的缺点是程序额外运行系统程序执行清屏操作,延长了程序执行时间。

方法2 :可以利用 Windows 提供的 API (应用程序接口)函数自定义这个函数。下面是一个简洁的版本:

#include <windows.h>
void clrscr() {    //清空屏幕
    HANDLE hdout = GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出设备的句柄
    CONSOLE_SCREEN_BUFFER_INFO csbi;    //定义表示屏幕缓冲区属性的变量
    GetConsoleScreenBufferInfo(hdout, &csbi);  //获取标准输出设备的屏幕缓冲区属性
    DWORD size = csbi.dwSize.X * csbi.dwSize.Y, num = 0; //定义双字节变量
    COORD pos = {0, 0};    //表示坐标的变量(初始化为左上角(0, 0)点)
    //把窗口缓冲区全部填充为空格并填充为默认颜色(清屏)
    FillConsoleOutputCharacter(hdout, ' ', size, pos, &num);
    FillConsoleOutputAttribute (hdout, csbi.wAttributes, size, pos, &num );
    SetConsoleCursorPosition(hdout, pos);    //光标定位到窗口左上角
}

注意,在上面代码中使用了Windows 的 API 函数,所以需要在程序中包含头文件 windows.h:

#include <windows.h>

应用举例

要想在 Visual C++ 或 GCC 中使用 gotoxy 函数,就需要把上面自定义的 gotoxy 函数写在自己的程序中。然后就可以在程序中调用该函数。下面是一个简单的例子:

#include <stdio.h>
#include <windows.h>
void clrscr() {    //清空屏幕
    HANDLE hdout = GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出设备的句柄
    CONSOLE_SCREEN_BUFFER_INFO csbi;    //定义表示屏幕缓冲区属性的变量
    GetConsoleScreenBufferInfo(hdout, &csbi);  //获取标准输出设备的屏幕缓冲区属性
    DWORD size = csbi.dwSize.X * csbi.dwSize.Y, num = 0; //定义双字节变量
    COORD pos = {0, 0};    //表示坐标的变量(初始化为左上角(0, 0)点)
    //把窗口缓冲区全部填充为空格并填充为默认颜色(清屏)
    FillConsoleOutputCharacter(hdout, ' ', size, pos, &num);
    FillConsoleOutputAttribute (hdout, csbi.wAttributes, size, pos, &num );
    SetConsoleCursorPosition(hdout, pos);    //光标定位到窗口左上角
int main(void) {
    printf("Hello, world!\n");
    printf("press any key to clear screen");