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

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;
}

问题分析与解决

核心问题

  1. 枚举类型输入处理错误:输入的体型是字符串(如"Medium"),但代码中用%u直接将字符串读入枚举变量Tam,这会把字符串的首字符ASCII值(比如'M'的ASCII是77)当作整数存入枚举,导致tamanho_para_string无法匹配到正确的枚举分支,输出空字符串或错误值。
  2. 输入解析链断裂:scanf读取字符串到unsigned int类型变量时会失败,输入缓冲区的指针位置混乱,后续的ac、hp、cr变量会读取到错误的内容,最终导致输出乱码。

修复步骤

  1. 在get_monstros函数中新增字符串变量,存储输入的体型字符串,将scanf格式中的%u改为%s读取该字符串。
  2. 添加字符串到枚举的映射逻辑,根据输入的体型字符串匹配对应的Tamanho枚举值。
  3. 新增默认处理,避免输入未知体型时出现错误。

修复后的完整代码

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:27:17