C语言结构体输入输出异常及枚举值处理问题求助
问题排查:结构体输入输出乱码问题
问题概述
定义Monstro结构体存储怪物名称、类型、体型(枚举Tamanho)、ac、hp、cr等信息,实现添加并打印怪物功能时,输入怪物信息后输出出现乱码,与预期不符。
输入输出示例
输入示例
2 Alexandre Orc Medium 10 10 10 Jose Human Large 10 10 10
实际输出
Alexandre - Orc 1984069797 6421572 -1113634697 Medium - 10 10 6421572 -1113634697
预期输出
Alexandre - Orc Medium 10 10 10 Jose - Human Large 10 10 10
问题代码
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <limits.h> #include <string.h> #include <math.h> typedef enum { Tiny, Small, Medium, Large, Huge, Gargantuan } Tamanho; struct Monstro { char nome[100]; char tipo[100]; Tamanho Tam; int ac; int hp; int cr; }; struct Monstro monstros(char *nome, char *tipo, Tamanho Tam, int ac, int hp, int cr) { struct Monstro m; strcpy(m.nome, nome); strcpy(m.tipo, tipo); m.Tam = Tam; m.ac = ac; m.hp = hp; m.cr = cr; return m; } const char* tamanho_para_string(Tamanho tam) { switch(tam) { case Tiny: return "Tiny"; case Small: return "Small"; case Medium: return "Medium"; case Large: return "Large"; case Huge: return "Huge"; case Gargantuan: return "Gargantuan"; default: return ""; } } int get_monstros(struct Monstro *a, int n) { char nome[100]; char tipo[100]; Tamanho Tam; int ac; int hp; int cr; int i = 0; while (i < n && scanf("%s %s %u %i %i %i", nome, tipo, &Tam, &ac, &hp, &cr) != EOF) { a[i++] = monstros(nome, tipo, Tam, ac, hp, cr); } return i; } void println_monstros(struct Monstro *m) { printf("%s - %s %s %d %d %d\n", m->nome, m->tipo, tamanho_para_string(m->Tam), m->ac, m->hp, m->cr); } void testF(void) { int n; scanf("%d", &n); struct Monstro a[n]; int i = get_monstros(a, n); for (int j = 0; j < i; j++) { println_monstros(&a[j]); } } int main() { testF(); return 0; }
问题分析与解决
核心问题
- 枚举类型输入处理错误:输入的体型是字符串(如"Medium"),但代码中用
%u直接将字符串读入枚举变量Tam,这会把字符串的首字符ASCII值(比如'M'的ASCII是77)当作整数存入枚举,导致tamanho_para_string无法匹配到正确的枚举分支,输出空字符串或错误值。 - 输入解析链断裂:
scanf读取字符串到unsigned int类型变量时会失败,输入缓冲区的指针位置混乱,后续的ac、hp、cr变量会读取到错误的内容,最终导致输出乱码。
修复步骤
- 在
get_monstros函数中新增字符串变量,存储输入的体型字符串,将scanf格式中的%u改为%s读取该字符串。 - 添加字符串到枚举的映射逻辑,根据输入的体型字符串匹配对应的
Tamanho枚举值。 - 新增默认处理,避免输入未知体型时出现错误。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <limits.h> #include <string.h> #include <math.h> typedef enum { Tiny, Small, Medium, Large, Huge, Gargantuan } Tamanho; struct Monstro { char nome[100]; char tipo[100]; Tamanho Tam; int ac; int hp; int cr; }; struct Monstro monstros(char *nome, char *tipo, Tamanho Tam, int ac, int hp, int cr) { struct Monstro m; strcpy(m.nome, nome); strcpy(m.tipo, tipo); m.Tam = Tam; m.ac = ac; m.hp = hp; m.cr = cr; return m; } const char* tamanho_para_string(Tamanho tam) { switch(tam) { case Tiny: return "Tiny"; case Small: return "Small"; case Medium: return "Medium"; case Large: return "Large"; case Huge: return "Huge"; case Gargantuan: return "Gargantuan"; default: return "Unknown"; } } // 将字符串转换为Tamanho枚举 Tamanho string_para_tamanho(const char* str) { if (strcmp(str, "Tiny") == 0) return Tiny; if (strcmp(str, "Small") == 0) return Small; if (strcmp(str, "Medium") == 0) return Medium; if (strcmp(str, "Large") == 0) return Large; if (strcmp(str, "Huge") == 0) return Huge; if (strcmp(str, "Gargantuan") == 0) return Gargantuan; return Tiny; // 默认返回Tiny,可按需调整 } int get_monstros(struct Monstro *a, int n) { char nome[100]; char tipo[100]; char tam_str[100]; // 存储输入的体型字符串 Tamanho Tam; int ac; int hp; int cr; int i = 0; // 修改scanf格式,读取体型字符串 while (i < n && scanf("%s %s %s %d %d %d", nome, tipo, tam_str, &ac, &hp, &cr) == 6) { Tam = string_para_tamanho(tam_str); // 转换为枚举 a[i++] = monstros(nome, tipo, Tam, ac, hp, cr); } return i; } void println_monstros(struct Monstro *m) { printf("%s - %s %s %d %d %d\n", m->nome, m->tipo, tamanho_para_string(m->Tam), m->ac, m->hp, m->cr); } void testF(void) { int n; scanf("%d", &n); struct Monstro a[n]; int i = get_monstros(a, n); for (int j = 0; j < i; j++) { println_monstros(&a[j]); } } int main() { testF(); return 0; }
测试结果
输入示例中的内容后,输出与预期一致:
Alexandre - Orc Medium 10 10 10 Jose - Human Large 10 10 10
内容的提问来源于stack exchange,提问作者andre Sousa
相关产品推荐
相关产品推荐

