Средний балл, связанный с некоторыми техническими проблемами

Я следил за всем в книге, но мой средний балл каждый раз меня подводит. Я отлаживал свою программу несколько раз, но напрасно.

Мой минимальный исполняемый код:

#include <limits.h>

#include <stdbool.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <string.h>

#define MAX_TESTS 5
#define MAXQUESTION 10000

bool myread(const char * format, void * address) {
  char buffer[1024];
  fgets(buffer, sizeof buffer, stdin);
  return sscanf(buffer, format, address) == 1;
}

struct struc {
  int a;

  int b;

  int c;

  int add;

  int grade;
};

int sj(int n) {
  int t;

  t = rand() % n;

  return t;
}

void ctm_i(struct struc * t) {
  {
    t -> a = sj(101);
    t -> c = sj(4);
    if (t -> c == 1) {
      t -> b = sj(101 - (t -> a));
      t -> add = (t -> a) + (t -> b);
    } else {
      t -> b = sj((t -> a) + 1);
      t -> add = (t -> a) - (t -> b);
    }
    t -> grade = 0;
  }
}

void tcm_i(struct struc * t, int n) {
  int ad;

  printf(" ***********************************************************************"
    "*********\n");

  printf(" ......................................................................."
    ".........\n");

  printf(" Question %d\n\n", n + 1);

  printf(" You have 3 attempts for this question\n\n");

  if (t -> c == 1)
    printf(" %d+%d= ", t -> a, t -> b);
  else
    printf(" %d-%d= ", t -> a, t -> b);

  myread(" %d", & ad);
  if (ad == t -> add)

  {
    t -> grade = 10;

    printf(" You earned 10 marks\n\n");
  } else {
    printf("\n Incorrect, you have 2 attempts remaining\n\n");
    printf(" ");
    myread(" %d", & ad);

    if (ad == t -> add)

    {

      t -> grade = 7;

      printf(" You earned 7 marks\n\n");
    } else {
      printf("\n Incorrect, you have 1 attempt remaining\n\n");
      printf(" ");
      myread(" %d", & ad);

      if (ad == t -> add)

      {

        t -> grade = 5;

        printf(" You earned 5 marks\n\n");
      } else {
        t -> grade = 0;

        printf("\n Failure, 0 mark\n\n");

        printf("\n The correct answer is %d\n\n", t -> add);
      }
    }
  }

  printf(" ......................................................................."
    ".........\n");

  printf(" ***********************************************************************"
    "*********\n");
}

void quiz(char name[]) {
  int rounds = 0;
  int highest = 0;
  int lowest = INT_MAX;
  float allScore = 0;
  float avg = 0.0;

  int i, j, g = 0;
  struct struc test[MAX_TESTS];

  srand((unsigned) time(NULL));

  for (;;) {
    rounds++;
    for (i = 0; i < MAX_TESTS; i++) // generate all questions
    {
      ctm_i( & test[i]);

      for (j = 0; j < i; j++)

        if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
          //if question is already present
          ctm_i( & test[i]); //then re-generate
    }
    printf("\n Are you ready? Press Enter key to continue. ");
    myread("", NULL);

    for (i = 1; i <= 5; i++) {
      printf(" *******************************************************************"
        "**"
        "***********\n");

      printf(" ..................................................................."
        ".."
        "...........\n");
    }

    // Take quiz
    for (i = 0; i < MAX_TESTS; i++)
      tcm_i( & test[i], i);

    printf(" End\n\n");

    bool done = false;
    bool unsure = true;
    bool showS = true;

    while (unsure) {
      unsure = false;
      puts("\n");
      if (showS) {
        puts(" Enter 'S' to show results");
      }
      puts(" Enter 'P' to play another round");
      puts(" Enter 'R' to return to main menu");
      char choice;
      printf(" ");
      myread(" %c", & choice);
      printf("\n");
      if (choice == 'r' || choice == 'R') {
        done = true;
      } else {

        ///////////////////////// Changes    /////////////

        g = 0;
        // calculate total score for current round
        for (i = 0; i < MAX_TESTS; i++) {
          g += test[i].grade; //add score of each question
        }
        allScore += g; //add current round's score to total
        avg = allScore / rounds; //average of all rounds

        if (g > highest) {
          highest = g;
        }

        if (g < lowest) {
          lowest = g;
        }

        if (choice == 'S' || choice == 's') {
          showS = false;
          if (rounds == 1) {
            printf(" Final score: %d/100\n", g); //display round score
            printf(" ****** Player: %s ******\n", name);
          } else {
            printf(" Round %d score: %d/100\n", rounds, g); //display round score
            printf(" Highest score: %d/100\n", highest);
            printf(" Lowest score : %d/100\n", lowest);
            printf(" Average score: %f/100\n", avg);
            printf(" ****** Player: %s ******\n", name);
          }
          unsure = true;
        } else if (choice == 'P' || choice == 'p') {
          /// nothing to be done here
          //we will display next test
        } else {
          puts(" Invalid input!");
          unsure = true;
        }

        ////////////////////////////////////

      }
    }
    if (done)
      break;
  }
}

int main() {
  char i1 = '1';
  char name[25]; // ig;
  printf("\n Welcome");

  printf("\n");
  while (i1 != 0) {

    printf("\n");
    //printf(" **********************Welcome %s! *********************\n", name);
    printf(" ************************ Main Menu of Maths Quiz ***************************\n");
    printf(" * 1.Enter Quiz                                                             *\n");
    printf(" * 2.Quit                                                                   *\n");
    printf(" ****************************************************************************\n");
    printf(" Please choose one from 1-2:\n");
    printf(" ");
    myread(" %c", & i1);
    switch (i1) {
    case '1':
      printf("\n Enter Quiz:\n");
      quiz(name); // calling quiz function defined in file "maincode.c"
      break;
    case '2':
      printf(" Quit.\n\n");
    }
  }
  return 0;
}

Надеюсь, что выполнил определение MRE. Так что я отрезал несколько напыщенных строк, а те, что остались, я думаю, самые важные.

Опубликуйте полный пример. Вы не указали источник для myread() или ctm_i()

Andrew Henle 24.12.2020 14:19

Полный пример? Вы имеете в виду полный код?????

TheNovice 24.12.2020 14:21

@TheNovice нет, не полный код, а минимальный воспроизводимый пример. Это означает некоторую работу для вас, но вы можете даже сами найти проблему в процессе.

Jabberwocky 24.12.2020 14:22

Если вы не можете решить проблему с помощью полного кода, почему вы ожидаете, что другие решат ее с помощью только части кода? Пожалуйста, прочтите stackoverflow.com/help/how-to-ask

Andrew Henle 24.12.2020 14:22

Является ли myread("%c", &choice); вершиной непоказанной проблемы с вводом? Обычно мы добавляем пробел в этот спецификатор формата scanf, например " %c", чтобы заполнить новую строку, оставшуюся во входном буфере.

Weather Vane 24.12.2020 14:26

Хм, я думаю, что нет минимального воспроизводимого примера, мой код взаимосвязан.

TheNovice 24.12.2020 14:29

@WeatherVane Спасибо за совет! Я думаю, в этом и есть моя проблема!

TheNovice 24.12.2020 14:35

Извините, я неправильно ввел баллы.

TheNovice 24.12.2020 14:38

Пожалуйста, копируйте/вставляйте только из фактического кода, а также входных и выходных данных.

Weather Vane 24.12.2020 14:41

Всегда есть MRE, @TheNovice, но его создание иногда требует больше работы. Прочитайте ссылку, которую вы ранее предоставили: создание MRE часто требует больше работы, чем просто вырезание выбранных частей вашего кода. Кроме того, это очень полезный навык, так как он сам по себе является мощной техникой отладки.

John Bollinger 24.12.2020 14:55

Хорошо, я думаю, что мне действительно нужно создать MRE прямо сейчас, так как средний балл по-прежнему неверен для игр, сыгранных в 3 раунда или выше.

TheNovice 24.12.2020 15:18

Итак, ребята, мой минимальный исполняемый код теперь на борту!

TheNovice 24.12.2020 15:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в вашей функции quiz и, в частности, в цикле while (unsure). В этом цикле вы добавляете самую последнюю оценку к промежуточной сумме:

allScore += g; //add current round's score to total

Это должно происходить один раз за сыгранный раунд. Но если пользователь вводит "S" или что-то недопустимое, ваша программа устанавливает

unsure = true;

что означает, что цикл будет запущен снова, прежде чем будет сыгран следующий раунд. Затем он добавляет самый последний результат во второй раз к общему итогу.

Самым логичным решением было бы вынести все расчеты итогов, максимума, минимума, среднего из цикла while. Цикл служит другой цели: он предназначен для взаимодействия с пользователем и составления отчетов, а не для обработки результатов.

возможный шанс повторного расчета нескольких средних значений для одного и того же раунда. Сохраняйте флаг, чтобы отслеживать подсчет очков, поэтому мы не будем делать то же самое более одного раза, пока игра не будет сыграна снова.

    #include <limits.h>

    #include <stdbool.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <time.h>

    #include <string.h>

    #define MAX_TESTS 5
    #define MAXQUESTION 10000

    bool myread(const char * format, void * address) {
      char buffer[1024];
      fgets(buffer, sizeof buffer, stdin);
      return sscanf(buffer, format, address) == 1;
    }

    struct struc {
      int a;

      int b;

      int c;

      int add;

      int grade;
    };

    int sj(int n) {
      int t;

      t = rand() % n;

      return t;
    }
    void ctm_i(struct struc * t) {
      {
        t -> a = sj(101);
        t -> c = sj(4);
        if (t -> c == 1) {
          t -> b = sj(101 - (t -> a));
          t -> add = (t -> a) + (t -> b);
        } else {
          t -> b = sj((t -> a) + 1);
          t -> add = (t -> a) - (t -> b);
        }
        t -> grade = 0;
      }
    }

    void tcm_i(struct struc * t, int n) {
      int ad;

      printf(" ***********************************************************************"
"*********\n");
      printf(" ......................................................................."
".........\n");

      printf(" Question %d\n\n", n + 1);

      printf(" You have 3 attempts for this question\n\n");

      if (t -> c == 1)
        printf(" %d+%d= ", t -> a, t -> b);
      else
        printf(" %d-%d= ", t -> a, t -> b);

      myread(" %d", & ad);
      if (ad == t -> add)

      {
        t -> grade = 10;

        printf(" You earned 10 marks\n\n");
      } else {
        printf("\n Incorrect, you have 2 attempts remaining\n\n");
        printf(" ");
        myread(" %d", & ad);

        if (ad == t -> add)

        {

          t -> grade = 7;

          printf(" You earned 7 marks\n\n");
        } else {
          printf("\n Incorrect, you have 1 attempt remaining\n\n");
          printf(" ");
          myread(" %d", & ad);

          if (ad == t -> add)

          {

            t -> grade = 5;

            printf(" You earned 5 marks\n\n");
          } else {
            t -> grade = 0;

            printf("\n Failure, 0 mark\n\n");

            printf("\n The correct answer is %d\n\n", t -> add);
          }
        }
      }

      printf(" ......................................................................."
".........\n");

      printf(" ***********************************************************************"
"*********\n");
    }

    void quiz(char name[]) {
      int rounds = 0;
      int highest = 0;
      int lowest = INT_MAX;
      float allScore = 0;
      float avg = 0.0;

      int i, j, g = 0;
      struct struc test[MAX_TESTS];

      srand((unsigned) time(NULL));

      for (;;) {
        rounds++;
        for (i = 0; i < MAX_TESTS; i++) // generate all questions
        {
          ctm_i( & test[i]);

          for (j = 0; j < i; j++)

            if (test[i].a == test[j].a && test[i].b == test[j].b && test[i].c == test[j].c)
              //if question is already present
              ctm_i( & test[i]); //then re-generate
        }
        printf("\n Are you ready? Press Enter key to continue. ");
        myread("", NULL);

        for (i = 1; i <= 5; i++) {
          printf(" *******************************************************************"
    "**"
    "***********\n");

          printf(" ..................................................................."
    ".."
    "...........\n");
        }

        // Take quiz
        for (i = 0; i < MAX_TESTS; i++)
          tcm_i( & test[i], i);

        printf(" End\n\n");

        bool done = false;
        bool unsure = true;
        bool showS = true;
        bool acct = false;

while (unsure) {
  unsure = false;
  puts("\n");
  if (showS) {
    puts(" Enter 'S' to show results");
  }
  puts(" Enter 'P' to play another round");
  puts(" Enter 'R' to return to main menu");
  char choice;
  printf(" ");
  myread(" %c", & choice);
  printf("\n");
  if (choice == 'r' || choice == 'R') {
    done = true;
  } else {

    ///////////////////////// Changes    /////////////
    if (false == acct) {
    g = 0;
    // calculate total score for current round
    for (i = 0; i < MAX_TESTS; i++) {
      g += test[i].grade; //add score of each question
    }
    allScore += g; //add current round's score to total
    avg = allScore / rounds; //average of all rounds

    if (g > highest) {
      highest = g;
    }

    if (g < lowest) {
      lowest = g;
    }
    acct = true;
    }
    if (showS &&(choice == 'S' || choice == 's')) {
      showS = false;
      if (rounds == 1) {
        printf(" Final score: %d/100\n", g); //display round score
        printf(" ****** Player: %s ******\n", name);
      } else {
        printf(" Round %d score: %d/100\n", rounds, g); //display round score
        printf(" Highest score: %d/100\n", highest);
        printf(" Lowest score : %d/100\n", lowest);
        printf(" Average score: %f/100\n", avg);
        printf(" ****** Player: %s ******\n", name);
      }
      unsure = true;
    } else if (choice == 'P' || choice == 'p') {
      /// nothing to be done here
      //we will display next test
    } else {
      puts(" Invalid input!");
      unsure = true;
    }

    ////////////////////////////////////

  }
}
if (done)
  break;
      }
    }

    int main() {
      char i1 = '1';
      char name[25]; // ig;
      printf("\n Welcome");

      printf("\n");
      while (i1 != 0) {

printf("\n");
//printf(" **********************Welcome %s! *********************\n", name);
printf(" ************************ Main Menu of Maths Quiz ***************************\n");
printf(" * 1.Enter Quiz                                                             *\n");
printf(" * 2.Quit                                                                   *\n");
printf(" ****************************************************************************\n");
printf(" Please choose one from 1-2:\n");
printf(" ");
myread(" %c", & i1);
switch (i1) {
case '1':
          printf("\n Enter Quiz:\n");
          quiz(name); // calling quiz function defined in file "maincode.c"
          break;
        case '2':
          printf(" Quit.\n\n");
        }
      }
      return 0;
    }

Выход:

     Enter 'S' to show results
      Enter 'P' to play another round
      Enter 'R' to return to main menu
      s

      Round 2 score: 47/100
      Highest score: 50/100
      Lowest score : 47/100
      Average score: 48.500000/100
      ****** Player:  ******

Спасибо, но я получаю Non-object type 'int (const char *)' is not assignable предупреждение за линию acct=true. Как решить эту проблему?

TheNovice 25.12.2020 03:01

Можно ли поделиться полным кодом и командой, используемой для компиляции. не вижу никаких предупреждений с cc <file> или «cc -Wall -Wextra -pedantic-errors avg3.c». т

Nishad C M 25.12.2020 05:12

Конечно! Вот ссылка на мой полный код paste.ubuntu.com/p/NW7qfcRQGS, буду очень признателен, если поможете решить это average score фиаско, которое длится уже больше недели. Спасибо.

TheNovice 25.12.2020 05:30

Кстати, в качестве IDE я использую Xcode v12.2.

TheNovice 25.12.2020 05:31

общий код компилируется для меня, не видя флага «acct» в коде. Я добавил флаг и скомпилировал, не видя никаких предупреждений, связанных с флагом. компиляция не дала никакой ошибки. В коде уже используется логическое значение, и мы добавляем новое логическое значение, которое не должно вызывать никаких проблем, единственной проблемой может быть отсутствие квадратных скобок или «;». результат :

Nishad C M 25.12.2020 06:47

1) добавлен флаг в строке 265, 265 bool acct_checked = false; 2) добавлена ​​проверка в строке "287" перед обработкой score , 286 if (acct_checked == false) { 3) изменение флага на true после обработки score в строке "306" и закрытия скобки в 307, 306 acct_checked = true;

Nishad C M 25.12.2020 06:48

Не могли бы вы прислать мне полный код, который вы исправили?

TheNovice 25.12.2020 06:50

Другие вопросы по теме