本文展示一個使用 ncurses 庫實現的簡單單屏文本編輯器,演示鍵盤輸入處理、光標移動、字符刪除、整行刪除等基本編輯功能,是理解終端交互與指針操作的優秀實踐案例。
#include#include #include int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); initscr(); clear(); noecho(); cbreak(); if (has_colors() == FALSE) { endwin(); printf("你的終端不支持色彩!\n"); return 1; } start_color(); mvprintw(5, COLS/2 - 10, "簡單編輯器 - 僅限於單個屏幕的編輯"); refresh(); init_pair(1, COLOR_GREEN, COLOR_BLACK); WINDOW *win1; int width = COLS - 14; int height = LINES - 14; int x, y; win1 = newwin(height, width, 7, 7); keypad(win1, TRUE); wattron(win1, COLOR_PAIR(1)); box(win1, ACS_VLINE, ACS_HLINE); wrefresh(win1); getyx(win1, y, x); ++y; ++x; // 移至內部可編輯區域起始位置 while (1) { int c = mvwgetch(win1, y, x); switch (c) { case KEY_RIGHT: ++x; if (x >= width - 1) { ++y; x = 1; } break; case KEY_LEFT: --x; if (x < 1) { --y; x = width - 2; } break; case KEY_UP: --y; if (y < 1) y = height - 2; break; case KEY_DOWN: ++y; if (y >= height - 1) y = 1; break; case 10: // Enter ++y; if (y >= height - 1) y = 1; break; case KEY_F(1): // 退出確認 mvprintw(LINES - 3, 2, "退出編輯器嗎?"); mvprintw(LINES - 2, 2, " "); refresh(); int ans = getch(); if (ans == 'Y' || ans == 'y') { mvprintw(LINES - 2, 2, "是\n"); refresh(); endwin(); return 0; } else { mvprintw(LINES - 2, 2, "否\n"); refresh(); } break; case KEY_F(12): // 刪除整行 wdeleteln(win1); winsertln(win1); box(win1, ACS_VLINE, ACS_HLINE); break; case KEY_DC: // 刪除字符 mvwprintw(win1, y, x, " "); break; default: // 普通字符插入 mvwprintw(win1, y, x, "%c", c); ++x; if (x >= width - 1) { ++y; x = 1; } if (y >= height - 1) y = 1; wrefresh(win1); } } // 理論上不可達 wattroff(win1, COLOR_PAIR(1)); endwin(); return 0; }
gcc -lncursesw editor.c -o myeditor ./myeditor
initscr()、cbreak()、noecho()、keypad() 開啟功能鍵支持。newwin() 創建子窗口,box() 繪製邊框,wrefresh() 刷新顯示。getyx() 獲取當前光標位置,mvwgetch() 在指定位置讀取字符並隱式移動光標。wdeleteln() 刪除當前行並上移後續行,winsertln() 插入空行,配合 box() 重繪邊框保持界面完整。start_color()、init_pair()、wattron() 設置窗口顏色屬性。
這個簡單的編輯器雖功能有限,但完整展示了 ncurses 核心 API 的使用方式,特別是窗口操作、鍵盤事件處理、光標移動邏輯與行級編輯操作。它是學習終端 UI 開發、指針與內存操作在實際項目中應用的優秀入門項目。