感谢:博主 整理好了我想要的 API。
- 环境: win10 下的 DOS 窗口 + vscode 终端(powershell)
- gcc version 8.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)
- 标准: C99
代码
#include <stdio.h>
#include <windows.h>
void gotoxy(int x, int y) {
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
//获取光标的位置x
int wherex() { CONSOLE_SCREEN_BUFFER_INFO pBuffer; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer); return (pBuffer.dwCursorPosition.X); }
//获取光标的位置y
int wherey() { CONSOLE_SCREEN_BUFFER_INFO pBuffer; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &pBuffer); return (pBuffer.dwCursorPosition.Y); }
// 回退到上行行首,x = 0, y - 1
void back() { gotoxy(0, wherey() - 1); }
// 从数组指定位置开始打印字符串(传入是注意: &arr[index], 要有 & )
void printArr(char c[]) { int i = 0; while (c[i]) printf("%c", c[i++]); }
// 模拟 vim 界面,将用户输入的文本信息(包括换行空格)保存在 content 中
void f() {
char content[1024] = {0};
while (1) {
char c = getch();
if (c >= 0x20 && c <= 0x7F) { // 键盘上的基本字符(字母、数字、符号)
sprintf(content, "%s%c", content, c);
printf("%c", c);
} else if(c == 13) { // 按下 enter 回车, 注意这里的输入是 13, 但存起来却是 10 '\n'
sprintf(content, "%s\n", content);
printf("\n");
} else if (c == 8) { // 删除字符
int i = 1;
while (content[i]) i++; // 有初始化 content 为0, 不怕死循环
i--;
if (content[i] == 10) { // 删除已到达行首
content[i] = 0;
back(); // 回退到上行行首
int j = i;
while (j >= 0 && content[j] != 10) j--;
printArr(&content[j+1]);
continue;
}
if (content[i] >= 0x20 && content[i] <= 0x7F) {
content[i] = 0;
printf("\b \b");
continue;
}
// 不是基本字符, 默认就是中文(鸵鸟算法), 中文占两字节.
content[i-1] = 0;
printf("\b\b \b\b");
} else if (c == 27) { // esc 按键
break;
} else if (c < 0) { // 期待的是这里接收的全部都是汉字(可能有意外)
// 上下左右按键,占用两个字节, 高 4 位均为 -32 故此处将其吸收掉
if (c == -32) { // 如果遇到有中文输入不了,则可能是在这里被吸收了(鸵鸟算法思维)
getch();
continue;
}
sprintf(content, "%s%c", content, c);
printf("%c", c);
}
}
printf("\n***********你输入的数据:\n%s\n", content);
}
int main() {
f();
return 0;
}