C语言int转char受控转换及打印异常:历史标记显示为88
原代码
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <stdbool.h> #define SPN 5 #define BTT 10 #define MARKER 'X' void create_pirolito(int matriz[SPN][SPN]); void create_retardado(int list[BTT]); void compare(int matriz[SPN][SPN], int list[BTT]); void print_list(int list[BTT]); void print_matriz(int matriz[SPN][SPN]); // 创建矩阵 void create_pirolito(int matriz[SPN][SPN]) { for(int i=0; i<SPN; i++) { for(int j=0; j<SPN; j++) { matriz[i][j]=rand()%25; } } } // 创建列表 void create_retardado(int list[BTT]) { for(int i=0; i<BTT; i++) { list[i]=rand()%20; } } int main() { int pirolito[SPN][SPN]; int retardado[BTT]; int z=0; const char *normal = "%2d"; const char *duplicate = "%2c"; create_pirolito(pirolito); create_retardado(retardado); while(z<100) { for(int i=0; i<BTT; i++) { printf("\n"); for(int j=0; j<SPN; j++) { for(int n=0; n<SPN; n++) { if(pirolito[j][n]==retardado[i]) { pirolito[j][n]=MARKER; printf("|"); printf(duplicate, pirolito[j][n]); } else { printf("|"); printf(normal, pirolito[j][n]); } } printf("|\n"); } printf("\n"); printf(" e o numero escolhido e: %2d", retardado[i]); getchar(); } z++; } return 0; }
问题描述
这段代码的功能是生成5×5的整数矩阵pirolito和包含10个整数的列表retardado,依次遍历列表中的每个数值,在矩阵中找到相等值后,将其替换为MARKER(字符'X'的ASCII值88)并打印为'X'。
当前代码存在问题:处理列表下一个元素时,之前标记为'X'的位置会显示成数值88,无法保持显示'X'。
预期输出
| 1| X| 2|15|18|
| X| X|17|24|21|
|12| 2|15| 9|13|
| 1|15| 1|22| X|
| X|18|17| 4| 7|e o numero escolhido e: 11
the number 11 and 10 is X
错误输出
| 1| X| 2|15|18|
|88| X|17|24|21|
|12| 2|15| 9|13|
| 1|15| 1|22| X|
| X|18|17| 4| 7|e o numero escolhido e: 11
the number 10 is now 88 not X
问题原因
打印逻辑有误:只有当矩阵值等于当前遍历的列表元素时,才会用字符格式打印'X';而之前已替换为88的位置,因为和当前列表元素不相等,会走else分支用整数格式打印,所以显示为88。
解决方案
修改打印判断逻辑:先检查矩阵值是否为MARKER,如果是则直接打印'X';否则再判断是否等于当前列表元素,替换后打印'X',或者打印原数值。
修改后的主函数核心代码如下:
int main() { int pirolito[SPN][SPN]; int retardado[BTT]; int z=0; const char *normal = "%2d"; const char *duplicate = "%2c"; create_pirolito(pirolito); create_retardado(retardado); while(z<100) { for(int i=0; i<BTT; i++) { printf("\n"); for(int j=0; j<SPN; j++) { for(int n=0; n<SPN; n++) { printf("|"); if(pirolito[j][n] == MARKER) { // 已标记的位置始终打印X printf(duplicate, MARKER); } else if(pirolito[j][n] == retardado[i]) { // 匹配当前值,标记后打印X pirolito[j][n] = MARKER; printf(duplicate, MARKER); } else { // 未标记且不匹配的位置打印原数值 printf(normal, pirolito[j][n]); } } printf("|\n"); } printf("\n"); printf(" e o numero escolhido e: %2d", retardado[i]); getchar(); } z++; } return 0; }
说明
修改后,无论处理哪个列表元素,所有已标记为MARKER的位置都会用字符格式打印'X',确保历史标记不会丢失,同时新匹配的数值也会正确标记并显示。
内容的提问来源于stack exchange,提问作者David feoerwg

