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

如何在str2为空时退出while循环?C代码问题排查

C代码循环退出逻辑与输出问题修复

问题描述

需要实现当str2为空时退出while循环,当前使用的循环条件为while (elementos <= tamanho - jogada || str2 == NULL);,但代码运行输出与预期不符,需解决循环退出逻辑及输出格式问题。

当前代码

#include <stdio.h>
#include <string.h>

#define BUFFER 100

unsigned int randaux() {
    static long seed = 1;
    return (((seed = seed * 214013L + 2531011L) >> 16) & 0x7fff);
}

/* Implementação do procedimento MostraLamberta */

unsigned int MostraLamberta(int *tabuleiro, int tamanho) {
    int i, casa, elementos;
    int jogada = 0;
    char novostr[BUFFER], str2[BUFFER];    /* novo vetor para receber os char */
    do {
        scanf("%d %d", &casa, &elementos);
        for (i = 0; i < tamanho; i++) {    /*Loop para percorrer o int tabuleiro um a um */
            if (tabuleiro[i] == 0) {       /*Comparar se for 0 vai para o vetor como O */
                novostr[i] = 'O';
            } else {            /* Se não vai para o vetor como X */
                novostr[i] = 'X';
            }
        }
        if (tamanho >= 10) {
            novostr[i] = '\0';
            for (i = 1; i < tamanho; i++) {
                if (i == 10) {
                    printf("%d", (i) / 10);
                } else {
                    printf(" ");
                }
            }
            printf("\n");
            for (i = 1; i < tamanho + 1; i++) {
                if (i >= 10) {
                    printf("%d", i % 10);
                } else {
                    printf("%d", i);
                }
                printf; // 语法错误
            }
        } else {
            for (i = 0; i < tamanho; i++) {
                if (i == 10) {
                    printf("%d", i % 10);
                } else {
                    printf("%d", i + 1);
                }
            }
        }
        printf("\n");
        novostr[i] = '\0';    /*Termina a string */
        jogada++;
        printf("%s", novostr);
        printf("\nJogada [%d]: %d %d", jogada, casa, elementos);    /*Imprime nova string */
        for (i = casa - 1; i < elementos + casa - 1; i++) {
            if (tabuleiro[i] == 0) {    /*Comparar se for 0 vai para o vetor como O */
                novostr[i] = 'X';
                tabuleiro[i] = 1;
                continue;
            } else {            /* Se não vai para o vetor como X */
                novostr[i] = 'O';
                tabuleiro[i] = 0;
                str2[i] = tabuleiro[i];
            }
            novostr[i] = '\0';

            printf("%d", str2[i]);//in here if its empty, the loop is over
        }
        printf("\n");

    } while (elementos <= tamanho - jogada || str2 == NULL);

    if (jogada % 2 == 0) {
        printf("Jogada inválida, perde jogador 2.");
    } else {
        printf("Jogada inválida, perde jogador 1.");
    }
}

void main() {
    int i, num, saltos, tamanho, tabuleiro[BUFFER];    /*Implementa as variáveis inteiras */
    scanf("%d %d", &tamanho, &saltos);

    // saltar os primeiros números aleatórios, para ter sequências distintas
    for (i = 0; i < saltos; i++)    /*Loop */
        randaux();            /*Chama a funcão randaux */

    /* Chamar o procedimento para gerar um novo tabuleiro */
    for (i = 0; i < tamanho; i++) {
        num = randaux();        /*Grava um numero aleatório numa nova variável */
        if (num % 2 == 0) {     /*VC* se o numero aleatório C) par ou impar */
            tabuleiro[i] = 0;
        } else {
            tabuleiro[i] = 1;
        }
    }

    MostraLamberta(tabuleiro, tamanho);    /*Chama a função e passa dois argumentos) */
}

输出对比

当前输出:
当前输出

预期输出:
预期输出

问题分析与修复方案

1. 循环退出逻辑错误

  • str2是局部数组,数组名是地址常量,永远不会等于NULL,str2 == NULL的判断完全无效。要判断str2是否为空,需检查是否是空字符串(strlen(str2) == 0),但首先要确保str2初始化为空。
  • 原循环条件的逻辑运算符使用错误:||表示只要满足一个条件就继续循环,不符合“当str2为空或elementos无效时退出”的需求,应改为&&,即仅当elementos有效且str2不为空时继续循环。

2. 输出格式问题

  • tamanho >= 10分支中的printf;是语法错误,无实际输出,应改为printf(" ");来分隔序号,保证格式对齐。
  • novostr的终止符设置位置混乱,应在转换tabuleiro到novostr的循环后直接设置novostr[tamanho] = '\0';,避免因分支导致的位置错误。
  • str2的赋值逻辑不完整:仅在tabuleiro[i] != 0时赋值,其余位置为随机值,导致strlen判断失效,需每次循环开始时清空str2。

3. 输入有效性检查缺失

未检查casa是否在合法范围(1~tamanho)、elementos是否为正,若输入无效应直接退出循环判定失败。

修改后的代码

#include <stdio.h>
#include <string.h>

#define BUFFER 100

unsigned int randaux() {
    static long seed = 1;
    return (((seed = seed * 214013L + 2531011L) >> 16) & 0x7fff);
}

unsigned int MostraLamberta(int *tabuleiro, int tamanho) {
    int i, casa, elementos;
    int jogada = 0;
    char novostr[BUFFER], str2[BUFFER] = {0}; // 初始化str2为空

    do {
        memset(str2, 0, sizeof(str2)); // 每次循环清空str2
        if (scanf("%d %d", &casa, &elementos) != 2) {
            // 输入错误直接退出
            break;
        }
        // 检查输入有效性
        if (casa < 1 || casa > tamanho || elementos <= 0 || elementos > tamanho - casa + 1) {
            break;
        }

        // 转换tabuleiro为字符字符串
        for (i = 0; i < tamanho; i++) {
            novostr[i] = tabuleiro[i] == 0 ? 'O' : 'X';
        }
        novostr[tamanho] = '\0'; // 正确设置字符串终止符

        // 打印序号头
        if (tamanho >= 10) {
            // 打印十位数字
            for (i = 1; i <= tamanho; i++) {
                if (i >= 10) {
                    printf("%d", i / 10);
                } else {
                    printf(" ");
                }
            }
            printf("\n");
            // 打印个位数字
            for (i = 1; i <= tamanho; i++) {
                printf("%d", i % 10);
                printf(" "); // 修复语法错误,添加空格分隔
            }
        } else {
            for (i = 1; i <= tamanho; i++) {
                printf("%d ", i);
            }
        }
        printf("\n");

        jogada++;
        printf("%s\n", novostr);
        printf("Jogada [%d]: %d %d\n", jogada, casa, elementos);

        // 执行翻转操作并记录到str2
        for (i = casa - 1; i < casa + elementos - 1; i++) {
            tabuleiro[i] = !tabuleiro[i];
            novostr[i] = tabuleiro[i] == 0 ? 'O' : 'X';
            str2[i] = tabuleiro[i]; // 记录修改后的值
        }
        novostr[tamanho] = '\0';
        // 打印修改后的棋盘
        printf("%s\n", novostr);

    } while (elementos <= tamanho - jogada && strlen(str2) > 0); // 修正循环条件

    if (jogada % 2 == 0) {
        printf("Jogada inválida, perde jogador 2.");
    } else {
        printf("Jogada inválida, perde jogador 1.");
    }
    return 0;
}

int main() { // 标准main函数返回值为int
    int i, num, saltos, tamanho, tabuleiro[BUFFER];
    scanf("%d %d", &tamanho, &saltos);

    for (i = 0; i < saltos; i++)
        randaux();

    for (i = 0; i < tamanho; i++) {
        num = randaux();
        tabuleiro[i] = num % 2 == 0 ? 0 : 1;
    }

    MostraLamberta(tabuleiro, tamanho);
    return 0;
}

关键修改点

  • 初始化并每次循环清空str2,用strlen(str2) > 0判断是否有修改
  • 修正循环条件的逻辑运算符为&&,确保仅合法时继续循环
  • 修复printf;的语法错误,添加空格分隔序号
  • 增加输入有效性检查,避免越界访问
  • 规范main函数的返回值类型为int,符合C标准

内容的提问来源于stack exchange,提问作者Ricardo Costa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:02:03