为何C语言程序读取输入后输出出现偏移?
C语言程序循环内输出偏移问题排查与解决
我是C语言新手,编写的程序读取输入后输出出现偏移,已排除终端问题(VS Code终端同样复现)。循环前输出正常,进入无限循环后出现偏移。
偏移输出示例
0000010000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000 0000000000000000000000000
程序代码
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ncurses.h> int main() { int rows, colls; rows = 10; colls = 25; int dysplay[rows][colls]; int grid[rows][colls]; int marked[rows*colls]; int x_axis, y_axis; x_axis = 0; y_axis = 0; srand(time(0)); //setting grid of mines and for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < colls; j++) { //get random nuber betwene 1 and 0 int num = rand() % 2; //give the coordinates value of random number grid[i][j] = num; dysplay[i][j] = 0; //print numbers printf("%d", num); } printf("\n"); } while (1) { initscr(); // Initialize ncurses cbreak(); // Disable line buffering and character echoing keypad(stdscr, TRUE); // Enable keypad function keys (e.g., function keys, arrow keys) noecho(); // Disable character echoing refresh(); // Refresh the screen char con = getch(); // Wait for a keypress if (con == 'd') { x_axis = x_axis + 1; dysplay[y_axis][x_axis] = 1; dysplay[y_axis][x_axis-1] = 0; } system("clear"); for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < colls; j++) { printf("%d", dysplay[i][j]); } printf("\n"); } } return 0; }
编译命令
gcc ./main.c -o ./main -Wall -Wextra -g3 -lncurses
问题原因
- 重复初始化ncurses:每次循环都调用
initscr(),重复初始化会打乱终端状态,直接导致输出偏移。initscr()仅需在程序启动时执行一次。 - 混合使用ncurses与标准IO:同时用ncurses的
getch()和标准库的printf()、system("clear"),两者终端控制逻辑冲突,引发排版异常。 - 数组越界未处理:
x_axis递增到colls-1时,x_axis+1会超出数组下标范围,触发未定义行为,加剧输出混乱。
修复方案
- 移除非必要初始化:将
initscr()、cbreak()等ncurses初始化代码移到循环外,仅执行一次。 - 统一使用ncurses函数:用
clear()替代system("clear"),printw()替代printf(),通过refresh()统一刷新屏幕。 - 添加边界检查:限制
x_axis的取值范围,避免数组越界。
修复后的代码:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <ncurses.h> int main() { int rows = 10; int colls = 25; int dysplay[rows][colls]; int grid[rows][colls]; int x_axis = 0; int y_axis = 0; srand(time(0)); // 初始化网格 for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < colls; j++) { int num = rand() % 2; grid[i][j] = num; dysplay[i][j] = 0; printf("%d", num); } printf("\n"); } // 仅初始化一次ncurses initscr(); cbreak(); keypad(stdscr, TRUE); noecho(); while (1) { char con = getch(); if (con == 'd') { // 边界检查,防止数组越界 if (x_axis < colls - 1) { dysplay[y_axis][x_axis] = 0; x_axis++; dysplay[y_axis][x_axis] = 1; } } // 使用ncurses原生函数控制屏幕 clear(); for (size_t i = 0; i < rows; i++) { for (size_t j = 0; j < colls; j++) { printw("%d", dysplay[i][j]); } printw("\n"); } refresh(); } endwin(); return 0; }
内容的提问来源于stack exchange,提问作者Komiš
相关产品推荐
相关产品推荐

