该篇博客主要是对下一篇博客《贪吃蛇游戏》的设计做铺垫,大家可以持续关注(点个关注哦😊)等待更新,以下是个人主页:
敲上瘾-CSDN博客
在我们写的程序运行起来后弹出的框就是控制台程序。而这个窗口我们是可以对它进行设置的,本章我们就来学习一下如何进行窗口大小设置,窗口标题设置,光标大小和坐标设置与虚拟键码。相关各种函数,数据类型,虚拟键码都配了链接(即蓝色字部分),大家可以通过点击链接学习来帮助理解。
一.窗口设置
1.窗口大小设置
mode命令可以实现这个操作,比如用cmd命令来设置窗口为30行100列,如下:
mode con cols = 100 lines = 30;
C语言来设置,如下:
system(" mode con cols = 100 lines = 30 ");
使用systme需要包含头文件<stdlib.h>。
2.窗口标题设置
title命令是用来设置标题的,用法如下:
system(" title 贪吃蛇")
这样可以把窗口标题设置为贪吃蛇,但要注意程序结束后窗口标题也会改变。
二.控制台坐标
COORD是Windows API中定义的一个结构体类型,表示一个字符在控制台缓冲区的坐标,如图:
COORD的声明:
创建变量并赋值:
COORD pos={ 5 , 7 };
三.光标设置
1.柄的获取
什么是柄?举个例子:
比如你在炒菜,一只手用来握锅铲,而另一只手如何控制锅呢?必然是要握住锅的把手,而不是直接用手去握锅面。在这里要操纵控制台就需要得到这个把手,这个把手就叫柄。
柄的类型是HANDLE,这也是WindowsAPI中定义的一个结构体。
获取柄的函数
GetStdHandle函数它⽤于从⼀个特定的标准设备(标准输⼊、标准输出或标准错误)中取得⼀个句柄(⽤来标识不同设备的数值),使⽤这个句柄可以操作设备。
声明如下:
HANDLE WINAPI GetStdHandle(_In_ DWORD nStdHandle);
参数可以取:
STD_INPUT_HANDLE 标准输入设备。 STD_OUTPUT_HANDLE 标准输出设备。 STD_ERROR_HANDLE 标准错误设备。
举个例子:
HANDLE houtput = NULL;
houtput = GetStdHandle(STD_OUTPUT_HANDLE);
2.光标信息获取
结构体 CONSOLE_CURSOR_INFO是储存光标信息的一个类型,声明如下:
typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
dwSize为光标的大小,bVisible为光标的透明度。
获取光标信息的函数GetConsoleCursorInfo
声明如下:
BOOL WINAPI GetConsoleCursorInfo(
HANDLE hConsoleOutput,
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);
用法举例:
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
3.设置光标信息
函数SetConsoleCursorInfo可用于光标信息设置
声明如下:
BOOL WINAPI SetConsoleCursorInfo(
HANDLE hConsoleOutput,
const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);
用法举例:
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
四.获取按键情况
GetAsyncKeyState函数用于获取按键状态
原型如下:
SHORT GetAsyncKeyState(int vKey);
功能:将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。
GetAsyncKeyState 的返回值是short类型,在上⼀次调⽤ GetAsyncKeyState 函数后,如果返回的16位的short数据中,最⾼位是1,说明按键的状态是按下,如果最⾼是0,说明按键的状态是起;如果最低位被置为1则说明,该按键被按过,否则为0。如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.
它的参数是一个虚拟键码,参考链接如下:
虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn
五.<locale.h>本地化
C语⾔字符默认是采⽤ASCII编码的,ASCII字符集采⽤的是单字节编码,且只使⽤了单字节中的低7位,最⾼位是没有使⽤的,可表⽰为0xxxxxxxx;可以看到,ASCII字符集共包含128个字符,在英语国家中,128个字符是基本够⽤的,但是,在其他国家语⾔中,⽐如,在法语中,字⺟上⽅有注⾳符号,它就⽆法⽤ASCII码表⽰。于是,⼀些欧洲国家就决定,利⽤字节中闲置的最⾼位编⼊新的符号。⽐如,法语中的é的编码为130(⼆进制10000010)。这样⼀来,这些欧洲国家使⽤的编码体系,可以表⽰最多256个符号。但是,这⾥⼜出现了新的问题。不同的国家有不同的字⺟,因此,哪怕它们都使⽤256个符号的编码⽅式,代表的字⺟却不⼀样。⽐如,130在法语编码中代表了é,在希伯来语编码中却代表了字⺟Gimel(),在俄语编码中⼜会代表另⼀个符号。但是不管怎样,所有这些编码⽅式中,0--127表⽰的符号是⼀样的,不⼀样的只是128--255的这⼀段。⾄于亚洲国家的⽂字,使⽤的符号就更多了,汉字就多达10万左右。⼀个字节只能表⽰256种符号,肯定是不够的,就必须使⽤多个字节表达⼀个符号。⽐如,简体中⽂常⻅的编码⽅式是GB2312,使⽤两个字节表⽰⼀个汉字,所以理论上最多可以表⽰256x256=65536个符号。
后来为了使C语⾔适应国际化,C语⾔的标准中不断加⼊了国际化的⽀持。⽐如:加⼊了宽字符的类型wchar_t 和宽字符的输⼊和输出函数,加⼊了<locale.h>头⽂件,其中提供了允许程序员针对特定地区(通常是国家或者说某种特定语⾔的地理区域)调整程序⾏为的函数
<locale.h>提供的函数⽤于控制C标准库中对于不同的地区会产⽣不⼀样⾏为的部分。
类项:
通过修改地区,程序可以改变它的⾏为来适应世界的不同区域。但地区的改变可能会影响库的许多部分,其中⼀部分可能是我们不希望修改的。所以C语⾔⽀持针对不同的类项进⾏修改,下⾯的⼀个宏,指定⼀个类项:
• LC_COLLATE:影响字符串⽐较函数 strcoll() 和 strxfrm() 。
• LC_CTYPE:影响字符处理函数的⾏为
• LC_MONETARY:影响货币格式。
• LC_NUMERIC:影响 printf() 的数字格式。
• LC_TIME:影响时间格式 strftime() 和 wcsftime() 。
• LC_ALL-针对所有类项修改,将以上所有类别设置为给定的语⾔环境。
setlocale函数⽤于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。setlocale的第⼀个参数可以是前⾯说明的类项中的⼀个,那么每次只会影响⼀个类项,如果第⼀个参数是LC_ALL,就会影响所有的类项。 C标准给第⼆个参数仅定义了2种可能取值:"C"(正常模式)和 " "(本地模式)。
在任意程序执⾏开始,都会隐藏式执⾏调⽤:
正常模式设置:
setlocale(LC_ALL, "C");
本地化模式设置:
setlocale(LC_ALL, " ");
那如果想在屏幕上打印宽字符,怎么打印呢?
宽字符的字⾯量必须加上前缀“L”,否则C语⾔会把字⾯量当作窄字符类型处理。前缀“L”在单引号前⾯,表⽰宽字符,对应 wprintf() 的占位符为 %lc ;在双引号前⾯,表⽰宽字符串,对应
wprintf() 的占位符为 %ls,例如:
#include<stdio.h>
#include<locale.h>
int main()
{setlocale(LC_ALL, "");wchar_t k=L'★';wprintf(L"%lc\n", k);wscanf(L"%lc", &k);wprintf(L"%lc\n", k);return 0;
}
输入汉字 于 ,输出结果为: