如何在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
相关产品推荐
相关产品推荐

