-1

I am practicing doing some programs on struct before I start practicing dynamic memory and I have been having this problem. This program is supposed to be simple, I have a Monster struct with the information that each monster will have and my main goal was to be able to create search functions to search monsters with a certain type with certain hp etc but I decided to start making simpler to test and simply print the monsters that were added, I start by saying how many monsters will be added (n) and then add their information, the problem is that my output gives like this :

Input:
2
Alexandre Orc Medium 10 10 10
Jose Human Large 10 10 10
Output:
Alexandre - Orc 1984069797 6421572 -1113634697
Medium - 10 10 6421572 -1113634697

And it should appear :

Alexander Orc Medium 10 10
Jose Human Large 10 10 10 

This is my code:

#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;
}
  • Have you tried running your code line-by-line in a debugger while monitoring the control flow and the values of all variables, in order to determine in which line your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Wenzel Mar 02 '23 at 20:59
  • `a[i++] = monstros(nome, tipo, Tam, ac, hp, cr);` looks like a roundabout way to assign values to the members in `a[i]`. You could `scanf` directly into `a[i]` instead: `while (i < n && scanf("%s %s %u %i %i %i", a[i].nome, a[i].tipo, &a[i].Tam, &a[i].ac, &a[i].hp, &a[i].cr) == 6) ++i;` – Ted Lyngmo Mar 02 '23 at 21:13

1 Answers1

1

scanf will not convert enumeration constant names in input to the enumeration constant values. %u tells it to match input for an unsigned int. You need to read the sizes as strings and write your own code to compare the strings to the names of the sizes.

You should always check whether the scanf result equals the number of assignments you want performed, not just check whether it equals EOF. For six ordinary conversions, you want the scanf result to be six. EOF means an error occurred or an end-of-file was indicated, but a return value of two, for example, means only two of the six requested assignments were performed.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312