Я следил за всем в книге, но мой средний балл каждый раз меня подводит. Я отлаживал свою программу несколько раз, но напрасно.
Мой минимальный исполняемый код:
#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. Так что я отрезал несколько напыщенных строк, а те, что остались, я думаю, самые важные.
Полный пример? Вы имеете в виду полный код?????
@TheNovice нет, не полный код, а минимальный воспроизводимый пример. Это означает некоторую работу для вас, но вы можете даже сами найти проблему в процессе.
Если вы не можете решить проблему с помощью полного кода, почему вы ожидаете, что другие решат ее с помощью только части кода? Пожалуйста, прочтите stackoverflow.com/help/how-to-ask
Является ли myread("%c", &choice);
вершиной непоказанной проблемы с вводом? Обычно мы добавляем пробел в этот спецификатор формата scanf
, например " %c"
, чтобы заполнить новую строку, оставшуюся во входном буфере.
Хм, я думаю, что нет минимального воспроизводимого примера, мой код взаимосвязан.
@WeatherVane Спасибо за совет! Я думаю, в этом и есть моя проблема!
Извините, я неправильно ввел баллы.
Пожалуйста, копируйте/вставляйте только из фактического кода, а также входных и выходных данных.
Всегда есть MRE, @TheNovice, но его создание иногда требует больше работы. Прочитайте ссылку, которую вы ранее предоставили: создание MRE часто требует больше работы, чем просто вырезание выбранных частей вашего кода. Кроме того, это очень полезный навык, так как он сам по себе является мощной техникой отладки.
Хорошо, я думаю, что мне действительно нужно создать MRE прямо сейчас, так как средний балл по-прежнему неверен для игр, сыгранных в 3 раунда или выше.
Итак, ребята, мой минимальный исполняемый код теперь на борту!
Проблема в вашей функции 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
. Как решить эту проблему?
Можно ли поделиться полным кодом и командой, используемой для компиляции. не вижу никаких предупреждений с cc <file> или «cc -Wall -Wextra -pedantic-errors avg3.c». т
Конечно! Вот ссылка на мой полный код paste.ubuntu.com/p/NW7qfcRQGS, буду очень признателен, если поможете решить это average score
фиаско, которое длится уже больше недели. Спасибо.
Кстати, в качестве IDE я использую Xcode v12.2.
общий код компилируется для меня, не видя флага «acct» в коде. Я добавил флаг и скомпилировал, не видя никаких предупреждений, связанных с флагом. компиляция не дала никакой ошибки. В коде уже используется логическое значение, и мы добавляем новое логическое значение, которое не должно вызывать никаких проблем, единственной проблемой может быть отсутствие квадратных скобок или «;». результат :
1) добавлен флаг в строке 265, 265 bool acct_checked = false; 2) добавлена проверка в строке "287" перед обработкой score , 286 if (acct_checked == false) { 3) изменение флага на true после обработки score в строке "306" и закрытия скобки в 307, 306 acct_checked = true;
Не могли бы вы прислать мне полный код, который вы исправили?
Опубликуйте полный пример. Вы не указали источник для
myread()
илиctm_i()