You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

问题原因

  1. 重复初始化ncurses:每次循环都调用initscr(),重复初始化会打乱终端状态,直接导致输出偏移。initscr()仅需在程序启动时执行一次。
  2. 混合使用ncurses与标准IO:同时用ncurses的getch()和标准库的printf()、system("clear"),两者终端控制逻辑冲突,引发排版异常。
  3. 数组越界未处理:x_axis递增到colls-1时,x_axis+1会超出数组下标范围,触发未定义行为,加剧输出混乱。

修复方案

  1. 移除非必要初始化:将initscr()、cbreak()等ncurses初始化代码移到循环外,仅执行一次。
  2. 统一使用ncurses函数:用clear()替代system("clear"),printw()替代printf(),通过refresh()统一刷新屏幕。
  3. 添加边界检查:限制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š

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:24:55