Почему моя программа вводит бесконечное l oop, когда я использую значения с плавающей запятой в While l oop? - PullRequest
2 голосов
/ 07 августа 2020

Мне было поручено сделать программу, чтобы прочитать имя одного ученика, 4 из его предметов и их соответствующие оценки. Я работал с циклами for и while, а также с операторами if, и вот мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main() {
    printf("Este programa captura el nombre de un alumno \n");
    printf  ("y cuatro de sus materias y sus respectivas notas\n");
    printf      ("Nota: El programa solo toma en cuenta los dos primeros\n");
    printf          ("decimales de la notas expresada.\n\n");
    
    char alumno[40] = {'\0'};
    char mat[4][20] = {'\0', '\0', '\0', '\0'};
    float calif[4] = {-1, -1, -1, -1};
    int i;
    
    while (alumno[0] == '\0') {
        printf("Ingresa el nombre del alumno: ");
        gets(alumno);
        if (alumno[0] == '\0') {
            printf("\nError. El alumno debe de llevar un nombre.");
            printf  ("\nTrata nuevamente\n\n");
        };
    };
    for (i = 0; i < 4; ++i) {
        while (mat[i][0] == '\0') {
            printf("Ingresa el nombre de la materia %d: ", i+1);
            gets(mat[i]);
            if (mat[i][0] == '\0') {
                printf("\nError. Las materias deben ser declaradas.");
                printf  ("\nTrata nuevamente.\n\n");
            };
        };
        while (calif[i] < 0 || calif[i] > 10) {
            printf("Ingrese la nota correspondiente a esta materia (0-10): ");
            scanf("%2.2f", calif[i]);
            if (calif[i] < 0 || calif[i] > 10) {
                printf("\nError. Debe ingresar una nota válidad entre 0 y 10.");
                printf  ("\nTrata nuevamente.\n\n");
            };
        };
    };
    
    return 0;
};

Кажется, программа работает нормально, пока не дойдет до точки. спросите оценку по первому предмету. Любая оценка, которую я поставил, вызывает бесконечное l oop. Я безрезультатно искал эту проблему. Так что, пожалуйста, дайте мне знать, что я здесь делаю не так.

1 Ответ

1 голос
/ 08 августа 2020

В вашем коде несколько проблем:

  • [основной] вы читаете метку с scanf("%2.2f", calif[i]): строка формата неверна, первая 2 означает чтение не более 2 байтов, а .2 - ошибка, поскольку scanf() вообще не поддерживает синтаксис точности. Это должно быть просто "%f", и вы должны передать адрес целевой переменной &calif[i] вместо ее значения. Кроме того, вы должны протестировать возвращаемое значение на предмет недопустимых или отсутствующих входных данных.

  • прототипом для main является int main(), int main(void) или int main(int argc, char *argv[]), отсутствующий результат type - устаревший синтаксис.

  • чтение ввода с gets() рискованно, так как нет способа предотвратить переполнение буфера с достаточно длинными входными строками. Вместо этого вы должны использовать scanf("%39s", alumno) или fgets(alumno, sizeof alumno, stdin) и проверить возвращаемое значение, чтобы обнаружить преждевременный конец входного потока. То же замечание для второго экземпляра gets().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...