[C語言]實現(xiàn)控制臺按鍵選擇式交互
在還沒有學GUI之前,大部分時候都是用控制臺黑窗口獲取用戶輸入的選項來進行判斷選擇了哪一個內(nèi)容。前幾天睡覺做夢的時候夢到在手搓一個用W和S來交互的控制臺,有點類似于xserver,今天晚上在現(xiàn)實中搓出來了,這是效果圖:

在寫這個程序之前,需要兩個預備知識:
printf的顏色控制:控制字符\033
這是一個轉義字符,實際為Esc,別的不多說,介紹用法:\033[屬性1;屬性2;....m
什么意思呢?我也理解得不太徹底——好吧,但是能用就行。\033[m是固定的符號,[和m中則聲明屬性,屬性與屬性之間用分號;隔開。
屬性都是數(shù)字,不同區(qū)間的數(shù)字作用的對象不同,有作用于字體的,有作用于背景的:
30~37作用于字體,而40~47作用于背景。
顏色有這些:
30 黑色?31 紅色?32 綠色?33 黃色?34 藍色?35 品紅?36 青色?37 白色(作用于字體)
40 黑色?41 紅色?42 綠色?43 黃色?44 藍色?45 品紅?46 青色?47 白色(作用于背景)
那么要打印一行背景為青色的字,只需要在需要打印的內(nèi)容前面加上\033[46m即可
printf("\033[46m青色背景\033[0m");
會發(fā)現(xiàn)后面還多了個\033[0m,這個控制符的作用是清空屬性,避免屬性被繼承到后面的行。
要打印紅色字體,青色背景的字呢,加一個屬性就好了,像這樣:
printf("\033[31;46m青色背景\033[0m");
<-這個是2,我至今沒弄懂這個東西插入代碼塊之后要怎么再起一個段落
頭文件conio.h中的函數(shù)getch();
getch()是一個不回顯函數(shù),當用戶按下某個字符時,函數(shù)自動讀取,無需按回車。當然,這個函數(shù)不在stdio.h里面,所以記得引入conio.h這個頭
不知道哪個版本VS之后就不許用getch();了,用_getch();代替。
這個函數(shù)讀取的按鍵值是其對應的十進制ASCII碼,在獲取值的時候定義int變量。
預備的東西完了,開始寫。
這個演示里面我分幾個函數(shù),主函數(shù)只作為入口,接下來是主要的功能函數(shù)menu()用于實現(xiàn)選擇菜單,globaljump(int is)用于跳轉各個函數(shù),剩下的ui1 ui2之類的是各功能的子菜單,但是里面不會有內(nèi)容了,因為寫到這里的時候我手已經(jīng)非常疼了寫不下去了。后面也不想寫了。
思路是這樣:
定義一個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);
代碼實現(xiàn):
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后面的就沒寫了,這只是個演示。
會有更優(yōu)寫法嗎?相信會有,但在這篇文章里面,更優(yōu)寫法不會出自我手。
感謝閱讀,祝好運~
覺得有幫助的話點個贊可以嗎╥﹏╥...