如何在ncurses窗口中打印数组内字符串且不超出窗口边框
问题根源
你的代码存在三个直接导致内容溢出边框的问题:
- 用标准库
printf输出内容,该函数默认向根窗口stdscr打印,不受你创建的子窗口win的边界约束 - 打印内容时没有做边界校验,也没有主动控制光标换行,内容输出到窗口边缘后不会自动适配边界,直接溢出
box(win,0,0)绘制的边框会占用窗口四周1格的空间,窗口实际可用内容区域为height-2行、width-2列,打印起始坐标应为窗口内的(1,1),从(0,0)位置打印会直接覆盖边框。
修复方案
- 替换输出函数:所有子窗口内的打印操作使用ncurses窗口专属API,向
win打印用wprintw,移动光标用wmove,获取当前光标位置用getyx宏,禁止用printf直接输出。 - 增加边界判断逻辑:打印每个单词前计算当前行剩余宽度,如果剩余宽度不足以容纳当前单词+后续空格,就将光标移动到下一行起始位置再打印,避免内容超框。
- 调整打印起始位置到(1,1),避开边框区域。
修复后可运行代码
#include <ncurses.h> #include <string> #include <cstdlib> #include <ctime> using namespace std; int main() { initscr(); cbreak(); noecho(); string wordList[19] = {"icecream", "computer", "dictionary", "algorithm", "the", "be", "to", "of", "and", "a", "your", "you", "year", "would", "work", "with", "will", "who", "which"}; string word[19]; // 窗口配置参数 int height = 9; int width = 75; int start_y = 10; int start_x = 10; // 创建窗口并绘制边框 WINDOW *win = newwin(height, width, start_y, start_x); box(win, 0, 0); // 初始化打印位置为边框内第一格 int cur_y = 1; int cur_x = 1; wmove(win, cur_y, cur_x); srand(time(0)); for(int i=0; i<19 ; i++){ word[i] = wordList[rand() % 19]; int word_len = word[i].size(); // 读取当前光标位置 getyx(win, cur_y, cur_x); // 剩余宽度不足时换行 if (cur_x + word_len + 1 > width - 1) { cur_y++; cur_x = 1; wmove(win, cur_y, cur_x); } // 向目标窗口打印内容 wprintw(win, "%s ", word[i].c_str()); } wrefresh(win); getch(); endwin(); return 0; }
补充说明
- 如果不想手动实现折行逻辑,可以在创建窗口后调用
scrollok(win, TRUE)开启窗口自动滚动折行,但该模式不会识别单词边界,可能把完整单词拆分到两行显示,显示效果不如手动判断宽度的方案。 - 所有窗口内容绘制完成后统一调用
wrefresh刷新即可,不需要绘制过程中重复刷新,避免出现屏幕闪烁。
内容的提问来源于stack exchange,提问作者Barety
相关产品推荐
相关产品推荐

