[C语言]实现控制台按键选择式交互
在还没有学GUI之前,大部分时候都是用控制台黑窗口获取用户输入的选项来进行判断选择了哪一个内容。前几天睡觉做梦的时候梦到在手搓一个用W和S来交互的控制台,有点类似于xserver,今天晚上在现实中搓出来了,这是效果图:

在写这个程序之前,需要两个预备知识:
printf的颜色控制:控制字符\033
这是一个转义字符,实际为Esc,别的不多说,介绍用法:\033[属性1;属性2;....m
什么意思呢?我也理解得不太彻底——好吧,但是能用就行。\033[m是固定的符号,[和m中则声明属性,属性与属性之间用分号;隔开。
属性都是数字,不同区间的数字作用的对象不同,有作用于字体的,有作用于背景的:
30~37作用于字体,而40~47作用于背景。
颜色有这些:
30 黑色 31 红色 32 绿色 33 黄色 34 蓝色 35 品红 36 青色 37 白色(作用于字体)
40 黑色 41 红色 42 绿色 43 黄色 44 蓝色 45 品红 46 青色 47 白色(作用于背景)
那么要打印一行背景为青色的字,只需要在需要打印的内容前面加上\033[46m即可
printf("\033[46m青色背景\033[0m");
会发现后面还多了个\033[0m,这个控制符的作用是清空属性,避免属性被继承到后面的行。
要打印红色字体,青色背景的字呢,加一个属性就好了,像这样:
printf("\033[31;46m青色背景\033[0m");
<-这个是2,我至今没弄懂这个东西插入代码块之后要怎么再起一个段落
头文件conio.h中的函数getch();
getch()是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车。当然,这个函数不在stdio.h里面,所以记得引入conio.h这个头
不知道哪个版本VS之后就不许用getch();了,用_getch();代替。
这个函数读取的按键值是其对应的十进制ASCII码,在获取值的时候定义int变量。
预备的东西完了,开始写。
这个演示里面我分几个函数,主函数只作为入口,接下来是主要的功能函数menu()用于实现选择菜单,globaljump(int is)用于跳转各个函数,剩下的ui1 ui2之类的是各功能的子菜单,但是里面不会有内容了,因为写到这里的时候我手已经非常疼了写不下去了。后面也不想写了。
思路是这样:
定义一个int类型的selected变量用于控制当前指向的菜单选项,初始值为0
定义一个int类型的choice变量用于储存用户输入
do{
把printf包含在一串if判断中,当selected指向该项,输出带背景色的文字,如果未指向该项则默认输出普通文字。
放置一个_getch()在判断后,赋值给choice
当放置switch选择语句,当choice是w时,selected-=1;当choice是s时,selected+=1;当choice是回车时,跳转到globaljump(int)以跳转至二级菜单
记得system("cls");清屏
}while(1);
代码实现:
main.c文件:
int main() {
extern void menu();
menu();
}
ui.c文件:
# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<windows.h>
#include<conio.h>
void menu(){ //主菜单
int selected = 0;
void globaljump(int);
void ui1(),ui2(), ui3(), ui4();//........
while (1) {
system("cls");
if (selected <= (-1)) { selected = 6; continue; } //选项到达头外时自动转到尾部,防止溢出
if (selected == 0)printf("\033[46m选项1\033[0m\n"); else printf("选项1\n");
if (selected == 1)printf("\033[46m选项2\033[0m\n"); else printf("选项2\n");
if (selected == 2)printf("\033[46m选项3\033[0m\n"); else printf("选项3\n");
if (selected == 3)printf("\033[46m选项4\033[0m\n"); else printf("选项4\n");
if (selected == 4)printf("\033[46m选项5\033[0m\n"); else printf("选项5\n");
if (selected == 5)printf("\033[46m选项6\033[0m\n"); else printf("选项6\n");
if (selected == 6)printf("\033[46m选项7\033[0m\n"); else printf("选项7\n");
if (selected >= 7) { selected = 0; continue; } //选项到达尾外时自动转到头部,防止溢出
puts("------------------------------");
puts("使用W和S选择选项,按回车键确定");
printf("\n\n\n\n\n");
printf("\t\t当前位置:%d\n",selected+1);
int choice = _getch();
switch (choice) {
case 119: { //w
selected -= 1;
break;
}
case 87: { //W
selected -= 1;
break;
}
case 115: { //s
selected += 1;
break;
}
case 83: { //S
selected += 1;
break;
}
case 13: { //回车
globaljump(selected); return;
}
}
}
}
void ui1() {
system("cls&&echo 选择了1");
exit(0);
}
void ui2() {
system("cls&&echo 选择了2");
exit(0);
}
void ui3() {
system("cls&&echo 选择了3");
exit(0);
}
//...
void globaljump(int is) {
switch (is) {
case 0: ui1(); break;
case 1: ui2(); break;
case 2: ui3(); break;
//...
}
}
选项4后面的就没写了,这只是个演示。
会有更优写法吗?相信会有,但在这篇文章里面,更优写法不会出自我手。
感谢阅读,祝好运~
觉得有帮助的话点个赞可以吗╥﹏╥...