Using local variables out of loop scope - c

I've got a function to calculate the total value of any given cards, it stores the sum of all current cards into score.
It also counts the number of aces in the deck.
I'm having trouble linking the value of ace and score after the loop.
I've implemented print statements in my actual file, it calculates correctly, but score and ace are obviously filled with random numbers after the for loop.
I don't know how to use those values outside of the for loop.
void calculateScore(Player * current_player)
{
int i, ace;
unsigned score;
ace = 0;
score = 0;
for (i=0; i<current_player->curnumcards; i++){
if (current_player->hand[i].c_face == 0){
ace++;
} else if (current_player->hand[i].c_face == 10){
score += 10;
} else if (current_player->hand[i].c_face == 11){
score += 10;
} else if (current_player->hand[i].c_face == 12){
score += 10;
} else {
score += ++current_player->hand[i].c_face;
}//end if to check ace/jack/queen/king
}//end for loop
if (ace>0){
for (;ace!=1;ace--){
if (score>11){
score += 1;
} else {
score += 11;
}//end if > 10 ace
}//end for loop to calculate ace's
}// end if ace loop
printf("Current score: %d\n", &score);
}

you should printf("Current score %u\n", score); You are printing the memory address &score, where you just want score. And it's unsigned so %u not %i.

ace, score = 0;
Takes the value of ace, does nothing with it, and assigns 0 to score. You probably want to assign 0 to both:
ace = score = 0;

Related

Assignment to expression with array type, assigning values to an array

i need to assign these values to the array but i keep receiving assignment to expression error, I'm wondering how I can assign values to those arrays. i try assigning the inputted value of arr into num but i believe I am missing something in that expression.
this codes job is to read the input of a temperature assign the input into a category of the type of day and give the average of the temperature
Enter a high temp reading (-99 to quit)> 100
Enter a high temp reading (-99 to quit)> 0
Enter a high temp reading (-99 to quit)> 50
Enter a high temp reading (-99 to quit)> -99
Hot days: 1
Pleasant days: 0
Cold days: 2
The average temperature was 50.00 degrees.
this is what an output should look like
#include <stdio.h>
int main(void){
//declare variables
int num[30];
int Cday[30];
int Pday[30];
int Hday[30];
int total;
int total_ave;
double ave;
int NHday=0;
int NPday=0;
int NCday=0;
int arr;
//ask input store into num, then decides if the number goes into which array
do{
printf("Enter a high temp reading (-99 to quit)>");
scanf ("%d", &arr);
num = arr;
if(arr == -99)
{
break;
}
else if(arr<=60 && arr>=0){
Cday = num;
}
else if(arr>=60 && arr<=84){
Pday = num;
}
else if(arr<=84 && arr>=200){
Hday = num;
}
}while(num >=0);
//calculating the average
total = sizeof(num);
for(int i = 0;i< total; i++){
total_ave = total_ave + num[i];
}
ave = total_ave / total;
//to print the amount of times each day was in a category
NHday = sizeof(Hday)/sizeof(Hday[0]);
NPday = sizeof(Pday)/sizeof(Pday[0]);
NCday = sizeof(Cday)/sizeof(Cday[0]);
//printing the final statement once all the values are calculated
printf("\nHot days:\t %d\n", NHday);
printf("Pleasant days:\t %d\n", NPday);
printf("Cold days:\t %d\n\n", NCday);
printf("The average temperature was %.2f degrees.", ave);
//stops compiling when -99 is entered not collected as information
//
//
return(0);
}
i would also appreciate to know if how i am calculating how many items are in the array with the NHday CDay and Pday Calculations is the correct way to do it.
i am also wondering if my calculation for the average is correct. any help is appreciated thank you.
You don't need arrays for the different types of days, just counter variables, which you increment based on the temperature range.
total should not be sizeof(num) for two reasons:
sizeof counts bytes, not array elements.
You only want the count of inputs, not the total size of the array. You can get the total by adding the counters of each type of day.
You don't have to put the temperatures in an array. Just add each day's temperature to the total_ave variable after the user enters it.
When you're calculating ave, you need to cast one of the variables to double so that floating point division will be used instead of integer division.
#include <stdio.h>
int main(void){
//declare variables
int num;
int total;
int total_ave = 0;
double ave;
int NHday=0;
int NPday=0;
int NCday=0;
//ask input store into num, then decides if the number goes into which array
while (1) {
printf("Enter a high temp reading (-99 to quit)>");
scanf ("%d", &num);
if(num == -99)
{
break;
}
else if(num<=60){
NCday++;
}
else if(num<=84){
NPday++;
}
else {
NHday++;
}
total_ave += num;
}
//calculating the average
total = NHday + NPday + NCday;
ave = (double)total_ave / total;
//printing the final statement once all the values are calculated
printf("\nHot days:\t %d\n", NHday);
printf("Pleasant days:\t %d\n", NPday);
printf("Cold days:\t %d\n\n", NCday);
printf("The average temperature was %.2f degrees.", ave);
return(0);
}
You are assigning arr value to num array without using index. Your while loop should be like
while(i<30){
printf("Enter a high temp reading (-99 to quit)>");
scanf ("%d", &arr);
if(arr==-99){
break;
}
num[i] = arr;
i++;
total++;
if(arr<=60 && arr>=0){
NCday++;
}
else if(arr>=60 && arr<=84){
NPday++;
}
else if(arr>=84 && arr<=200){
NHday++;
}
}
Now
total = sizeof(num);
This will give you the total size of num array which is 30*4=120 as int data type has 4 byte size.
If you are not filling all 30 values then you need to know the number of values your are going to use from that array. That's why I am incrementing total as I am inserting values in num array which will help later.
for(int i = 0;i< total; i++){
total_ave = total_ave + num[i];
}
ave = total_ave / total;
If you just want to know the count of cold, hot days then you can increment them in while loop and print those.
printf("\nHot days:\t %d\n", NHday);
printf("Pleasant days:\t %d\n", NPday);
printf("Cold days:\t %d\n\n", NCday);
And first initialize the variables.
int num[30];
int total=0;
int total_ave=0;
double ave;
int NHday=0;
int NPday=0;
int NCday=0;
int arr=0;
int i=0;

C program - Faulty scores output

C program. IDE used is Xcode v12.2.
The problem I am facing:
Faulty scores output. For each round, the program should output the highest and lowest scores and the average score if the player chooses to do so.
Scores output after playing for 1 round:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 92/100
Highest score: 92/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Scores output after playing for 2 rounds:
Enter 'S' to show results
Enter 'P' to play another round
Enter 'R' to return to the main menu
S
Round 0 score: 95/100
Highest score: 95/100
Lowest score: 92/100
Average score:inf
****** Player: MAX ******
Questions:
Why is 'Round 1' shown as 'Round 0'? And what does the 'inf' mean in the average score section? How do I turn 'inf' into a numerical output? After 2 rounds, the output 'Round 2' is still shown as 'Round 0' and the 'Average score' did not change to a numerical output.
What I have tried:
void quiz(char name[])
{
// function created to enclose quiz functionality apart from instructions
int rounds = 0;
int highest = 0;
int lowest = INT_MAX;
float allScore = 0;
float avg = 0;
int i, j, g = 0;
//char x;
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
}
//int ig = getchar();
char x;
x = getchar();
printf("\n Are you ready? Press Enter key to continue. ");
fflush(stdin);
while (x != '\n') {}
while (getchar() != '\n') {}
//getchar();
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 'Q' to quit");
puts(" Enter 'R' to return to main menu");
char choice;
printf(" ");
myread("%c", &choice);
if (choice == 'r' || choice == 'R')
{
done = true;
}
else if (choice == 'S' || choice == 's')
{
showS = false;
// calculate total score for current round
g = 0;
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 (rounds == 1)
{
printf(" Final score: %d/100\n", g); //display round score
printf(" ******Player: %s ******\n", name);
}
else
{
//puts("Whoops! Looks like highest/lowest have not been adjusted!");
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\n", avg);
printf(" ******Player: %s ******\n", name);
}
unsure = true;
//getchar();
}
else if (choice == 'P' || choice == 'p')
{
g = 0;
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
if (g > highest)
{
highest = g;
}
if (g < lowest)
{
lowest = g;
}
}
else
{
puts(" Invalid input!");
unsure = true;
}
}
if (done)
break;
}
}
Why is 'Round 1' shown as 'Round 0'?
The value of variable rounds is printed as the round number. If the round number always prints as 0 then it follows that rounds always has value zero at the point where that printf() call is made. And indeed, a look at all the appearances of that variable in your code shows that it is initialized to zero in its declaration, and then never modified.
And what does the 'inf' mean in
the average score section?
It means "infinity", and before even looking at your code, I would take it as a sign that you have somewhere used the result of dividing a non-zero floating-point number by zero.
In particular, the problem seems to be the same one as the previous: you use rounds as the divisor in your average score computation, and it is always zero.
How do I turn 'inf' into a numerical
output?
Change the faulty computation into a correct one. Properly maintaining the value of the rounds variable may be enough.
After 2 rounds, the output 'Round 2' is still shown as 'Round
0' and the 'Average score' did not change to a numerical output.
That's consistent with my observations above.

How do I stop a counter variable that keeps counting values from previous for loops? C Program

I am stuck on the last part of my homework assignment and hope I can get some guidance on what to do. The assignment is simple, I create a program that asks a user to input test scores until they type in my sentinel value of -1. Then the output displays the average of all imputed scores, this is to be repeated 4 times then the program exits. Everything works except my counter value. The counter keeps counting imputed scores from both the previous and current loops instead of only the current loop. So in iteration 2 it is giving me the average of all inputs from the first loop and the current loop.
Note: I haven't learned about arrays or anything else super advance yet.
I already initialized the count variable to 0 but I am can't seem to figure out why it ins't resetting per each loop. I moved the count=0 after the loop and before the loop and that doesn't do anything.
#include <stdio.h>
float calculateAverage(float, float);
FILE *fp;
int main(void)
{
int i;
float avg, score, sum = 0, count = 0;
fopen_s(&fp, "csis.txt", "w");
printf("***Average of Inputed Grades***\n");
for (i = 1; i <= 4; ++i)
{
do
{
printf("\nEnter Test Scores or -1 for average\n");
scanf_s("%f", &score);
fprintf(fp, "\nEnter Test Scores or -1 for average\n%f\n", score);
if (score != -1)
{
sum = sum + score;
count++;
}
} while (score >= 0 && score <= 100 && score != -1);
avg = calculateAverage(sum, count);
printf("\nThe Average for the entered test scores is:%.2lf\n", avg);
fprintf(fp, "\nThe Average for the entered test scores is:%.2lf\n", avg);
}
fclose(fp);
getchar();
return 0;
}
float calculateAverage(float sum, float count)
{
float avg = sum / count;
return (avg);
}
Expected results should display the average of the imputed test scores only for the current iteration then reset itself upon the next iteration.
The sum and count variables aren't resetting after each iteration of the do...while loop because you don't explicitly do so. You do set them to 0 at the start of the function where they're first defined, but you don't reset them again anyplace else.
You need to set both to 0 before entering the do...while loop:
for (i = 1; i <= 4; ++i)
{
sum = 0;
count = 0;
do
{
...
Even better, define sum and count at this point (as well as avg and score) since they're not used outside of the for loop:
for (i = 1; i <= 4; ++i)
{
float sum = 0, count = 0, avg, score;
do
{
...

Why are my values for sum and count being lost each loop?

I'm getting a consistent divide by zero error, even though each loop should be populating the variables. Code below:
#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
sum = 0;
count = 0;
grade = 0;
average = 0.0;
int coolvalue = 0;
while (coolvalue==0)
{
scanf("%d", &grade);
if (grade == -1)
{
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
}
else
{
if ((grade > 100) || (grade < -1))
{
printf("Error, incorrect input.\n");
break;
}
else
{
sum = +grade;
count = count + 1;
return count;
return sum;
}
}
}
coolvalue = 1;
}
int main(void)
{
while (1)
calculateAverage();
while (1) getchar();
return 0;
}
Even while using return, I'm not able to properly increment the value of sum or count.
There are multiple issues in your code.
scanf("%d", &grade); - you don't check the value returned by scanf(). It returns the number of values successfully read. If you enter a string of letters instead of a number, scanf("%d") returns 0 and it does not change the value of grade. Because of this the code will execute the rest of the loop using the previous value of grade. You should restart the loop if the value returned by scanf() is not 1:
if (scanf("%d", &grade) != 1) {
continue;
}
Assuming you enter 10 for grade this block of code executes:
sum = +grade;
count = count + 1;
return count;
return sum;
sum = +grade is the same as sum = grade. The + sign in front of grade doesn't have any effect. It is just the same as 0 + grade.
You want to add the value of grade to sum and it should be sum += grade. This is a shortcut of sum = sum + grade.
return count makes the function complete and return the value of count (which is 1 at this point) to the caller. The caller is the function main() but it doesn't use the return value in any way. Even more, your function is declared as returning void (i.e. nothing) and this renders return count incorrect (and the compiler should warn you about this).
return sum is never executed (the compiler should warn you about it being dead code) because the function completes and the execution is passed back to the caller because of the return count statement above it.
Remove both return statements. They must not stay here.
If you enter -1 for grade, this block of code is executed:
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
sum, sizeof(double) is an expression that does not have any effect; it takes the value of sum then discards it then takes the value of sizeof(double) (which is a constant) and discards it too. The compiler does not even generate code for it.
the same as above for count, sizeof(double);
average = (sum / count);:
the parenthesis are useless;
because both sum and count are integers, sum / count is also an integer (the integral result of sum / count, the remainder is ignored).
you declared average as double; to get a double result you have to cast one of the values to double on the division: average = (double)sum / count;
if you enter -1 as the first value when the program starts, count is 0 when this code is executed and the division fails (division by zero).
printf("%lf", &average); - you want to print the value of average but you print its address in memory. Remove the & operator; it is required by scanf() (to know where to put the read values). It is not required by printf(); the compiler generates code that passes to printf() the values to print.
break; - it passes the execution control after the innermost switch or loop statement (do, while or for). It is correct here and makes the variable coolvalue useless. You can simply remove coolvalue and use while (1) instead.
All in all, your function should look like:
void calculateAverage()
{
int sum = 0;
int count = 0;
int grade = 0;
double average = 0.0;
while (1) {
if (scanf("%d", &grade) != 1) {
// Invalid value (not a number); ignore it
continue;
}
// A value of -1 signals the end of the input
if (grade == -1) {
if (count > 0) {
// Show the average
average = (double)sum / count;
printf("Average: %lf\n", average);
} else {
// Cannot compute the average
puts("You didn't enter any value. Cannot compute the average.\n");
}
// End function
return;
}
if ((grade < -1) || (100 < grade)) {
puts("Error, incorrect input.\n");
// Invalid input, ignore it
continue;
}
sum += grade;
count ++;
}
}
Quite a few corrections need to be made.
The while loop in the calculateAverage() function. That's an infinite loop buddy, because you are not changing the value of that coolValue variable anywhere inside, instead you make it 1 only when it exits the loops, which it never will.
So, use while(1) {...}, and inside it, check for the stopping condition, i.e, if (grade == -1) { ... } and inside it calculate and print the average and return. This will automatically break the while.
You're not checking if the input grade is actually a valid integer or not. Check the value of scanf for that, i.e, use if (scanf("%d", &grade) != 1) { ... }
The expression sum = +grade; is just another way of writing sum = 0+grade which in turn is nothing but sum = grade. Replace this with sum += grade;. This is the right way to write a shorthand for addition.
Two return statements..a very wrong idea. First of all, a function can have just one return(in an obvious way I mean, at once). Secondly, the function calculateAverage() is of return-type void. there's no way how you can return double value from it. So remove these two statements.
I have attached the code below which works. Also do go through the output which I have attached.
CODE:
#include <stdio.h>
void calculateAverage()
{
int grade, count = 0, sum = 0;
double average;
printf("\nenter the grades... enter -1 to terminate the entries\n.");
while (1) {
printf("\nEnter the grade: ");
if (scanf("%d", &grade) != 1) {
printf("\nInvalid characters entered!!!");
continue;
}
else if(((grade > 100) || (grade < -1))) {
printf("\nInvalid grade entered!!!");
continue;
}
else {
if (grade == -1) {
average = sum/count;
printf("\nAverage value of grades: %.3lf",average);
return;
}
else {
sum += grade;
count++;
}
}
}
}
int main(void)
{
calculateAverage();
return 0;
}
OUTPUT:
enter the grades... enter -1 to terminate the entries.
Enter the grade: 50
Enter the grade: 100
Enter the grade: 60
Enter the grade: -1
Average value of grades: 70.000
Perhaps it is better for the function to be of type double instead of void. Although it is not my favorite solution it is close to what you want.
#include <stdio.h>
double calculateAverage(void)
{
double average;
int sum = 0, count=0, grade;
while (1)
{
scanf("%d", &grade);
if ((grade > 100) || (grade < -1))
printf("Error, incorrect input.\n");
else if (grade != -1)
{sum = sum+ grade; count = count + 1;}
else
break;
}
if (count==0)
average=-1.0; //none valid input. Notify the main()
else
average=(double)sum/count;
return average;
}
int main(void)
{
double result;
result= calculateAverage();
if (result!=-1.0)
printf("\n average= %lf",result);
else
printf("No grades to calculate average");
getchar();
return 0;
}

How do I adjust this code to allow for an unspecified number of positive integers

I am completely new to programming and I'm currently taking a Intro to programming course. I need to adjust the below code to allow for an unspecified number of positive integers. I've looked this up and it seems to not take the average correctly. Please help. Thank you.
#include <stdio.h>
int main ()
{
/* variable definition: */
int count, value, sum;
double avg;
/* Initialize variables */
count = 0;
sum = 0;
avg = 0.0;
// Loop through to input values
while (count < 20)
{
printf("Enter a positive Integer\n");
scanf("%d", &value);
if (value >= 0) {
sum = sum + value;
count = count + 1;
}
else {
printf("Value must be positive\n");
}
}
// Calculate avg. Need to type cast since two integers will yield an
// integer
avg = (double) sum/count;
printf("average is %lf\n ", avg );
return 0;
}
You can use infinite loop and check for negative value and the return result of scanf as conditions to break.
Sample code looks like:
for(;;)
{
printf("Enter a positive Integer\n");
if(scanf("%d", &value) == 1 )
{
if (value >= 0) {
sum = sum + value;
count = count + 1;
}
else {
printf("Value must be positive\n");
break;
}
}
else
{
break;
}
}
Also, your initialization code is ok, but can be done cleaner this way (there is no need to separate between declaration and initialization - you can group them into one line):
int count = 0, value = 0, sum = 0;
double avg = 0;

Resources