"goto" command creating infinite loop in loop "for"

0

I want to simulate a school database that collects names, math and physics grades, and calculates the mean of both to 5 students (defined in a string of struct ).

Any grade above 10 would be allowed, with no lock for that. Students would easily have grades above 10. I then thought about doing a condition with if-else and I used goto , positioning it back at the beginning of the grading request.

See the following code:

#include<stdio.h>
#include<locale.h>

int main(void){

setlocale(LC_ALL,"Portuguese");

struct Aluno{
    char nome[10];
    float notaMath, notaPhysics, media;
};

struct Aluno aluno[5];

int contador;

//Entrada de dados via teclado
for(contador = 0; contador < 5; contador++){
    printf("Nome do aluno %d: ", contador+1);
    scanf("%s",&aluno[contador].nome);

    RETORNO1:
    printf("Nota de matemática: ");
    scanf("%f",&aluno[contador].notaMath);
    if(aluno[contador].notaMath > 10.0){
        printf("Apenas notas até 10.\n");
        goto RETORNO1;
    }
    else{
        goto POINT1;
    }

    POINT1:
    RETORNO2:
    printf("Nota de física: ");
    scanf("%f",&aluno[contador].notaPhysics);
    if(aluno[contador].notaPhysics > 10.0){
        printf("Apenas notas até 10.\n");
        goto RETORNO2;
    }
    else{
        goto POINT2;
    }

    POINT2:
    aluno[contador].media = (aluno[contador].notaMath + aluno[contador].notaPhysics)/2;

    printf("\n");
}

printf("\n\n");

printf("------------Informações dos Alunos------------\n");
for(contador = 0; contador < 5; contador++){
    printf("Nome do aluno %d: %s\n", contador+1, aluno[contador].nome);
    printf("Nota de matemática: %.1f\n", aluno[contador].notaMath);
    printf("Nota de física: %.1f\n", aluno[contador].notaPhysics);
    printf("Média das notas: %.1f\n", aluno[contador].media);
    printf("\n\n");
}
}

In this case, when you put any floating point values greater than 10, it prints "only notes up to 10" and actually returns to the set point, all ok. But, if I put some floating-point value, type 10.5, it goes into loop infinity.

Without placing goto and POINT s and RETORNO s it simply skips many of the following statements and goes forward in the for loop.

Running example (data copied from .exe ):

"Nome do aluno 1: Jonathan
 Nota de matemática: 10.5
 Nota de física:
 Nome do aluno 2: Nota de matemática:"
    
asked by anonymous 28.09.2017 / 14:52

2 answers

0

Good how you want to have the user rewrite in the same house, if the > 10, you can do the following, in this code snippet you can lower your counter, this way it will return you to the same address:

scanf("%f %f",&aluno[contador].notaPhysics, &aluno[contador].notaMath);
if(aluno[contador].notaPhysics > 10.0 || aluno[contador].notaMath > 10.0){
    printf("Apenas notas até 10.\n");
    contador--;
}

But if you want to use Goto, I suggest that you remove your RETURN1 and RETURN2 and also remove the else.

    
28.09.2017 / 15:02
3

The code had some errors that I have corrected. I improved the style a bit too.

goto is almost never right . It can almost always be replaced by a if or a while , which is the case. What you want clearly is a loop of repetition until the person types the correct one, so make a loop, it's much simpler. Just leave it when the value you entered is valid.

#include <stdio.h>
#include <locale.h>

int main(void) {
    setlocale(LC_ALL,"Portuguese");
    struct Aluno {
        char nome[10];
        float notaMath, notaPhysics, media;
    } aluno[5];
    for (int contador = 0; contador < 5; contador++) {
        printf("Nome do aluno %d: ", contador + 1);
        scanf("%s", aluno[contador].nome);
        while (1) {
            printf("Nota de matemática: ");
            scanf("%f", &aluno[contador].notaMath);
            if (aluno[contador].notaMath > 10.0) {
                printf("Apenas notas até 10.\n");
            } else {
                break;
            }
        }
        while (1) {
            printf("Nota de física: ");
            scanf("%f", &aluno[contador].notaPhysics);
            if (aluno[contador].notaPhysics > 10.0) {
                printf("Apenas notas até 10.\n");
            } else {
                break;
            }
        }
        aluno[contador].media = (aluno[contador].notaMath + aluno[contador].notaPhysics) / 2;
        printf("\n");
    }
    printf("\n\n------------Informações dos Alunos------------\n");
    for (int contador = 0; contador < 5; contador++) {
        printf("Nome do aluno %d: %s\n", contador+1, aluno[contador].nome);
        printf("Nota de matemática: %.1f\n", aluno[contador].notaMath);
        printf("Nota de física: %.1f\n", aluno[contador].notaPhysics);
        printf("Média das notas: %.1f\n", aluno[contador].media);
        printf("\n\n");
    }
}

See running on ideone . And no Coding Ground . Also put it in GitHub for future reference .

I left contador , but I prefer i , I think very verbose, everyone knows what i is, I think even more readable. I would have other tips for writing better code, but it goes beyond the scope of the question.

    
28.09.2017 / 15:07