display highest/lowest and the avg of inputed marks - C programming - c

I'm writing a c program for my intro class and I'm stuck on the if/else statements. we have to output the highest,lowest grade entered as well as the avg for those. Marks entered must be between 0-100. this is my code so far, i can't seem to figure it out, thanks for any advice! :
#include <stdio.h>
int main (void)
{
int numberofMarks;
int i;
int x;
int y;
int numofPasses=1;
int numofFails=1;
float sumpassedMarks =0;
float sumfailedMarks=0;
float markEntered=0;
float highestMark=0;
float lowestMark=0;
float totalMark=0;
float avgofMarks=0;
float avgpassedMarks=0;
float avgfailedMarks=0;
printf (" ---=== IPC mark Analyser ===---\n");
printf ("Please enter the number of marks(between 3 and 40): ");
scanf ("%d", &numberofMarks);
//asks user for number of marks, only takes 3-40, otherwise outputs error msg
for (i=1 ; (numberofMarks < 3)||(numberofMarks > 40) ; i++) {
printf ("Invalid number, enter a number between 3 and 40 inclusive: ");
scanf ("%d", &numberofMarks);
}
//for loop recieves the mark
for (x=1 ;(x <= numberofMarks) ; x++) {
printf ("%d> ", x);
scanf ("%f", &markEntered);
//contd loop..loop makes sure mark entered is between 1-100
for (y=1; (markEntered <0)||(markEntered>100); y++)
{
printf ("Error, Enter values between 0 and 100 incluisve.\n");
printf ("%d> ", x);
scanf ("%f", &markEntered);
if (markEntered >= 50) {
numofPasses=numofPasses+1;
}
if else (markEntered <= 49) {
numofFails = numofFails+1;
}
if else (markEntered > highestMark) {
highestMark = markEntered;
}
else (markEntered < lowestMark) {
lowestMark = markEntered;
}
}
//adds the mark entered to all the marks entered for a overall sum
totalMark = totalMark + markEntered;
}
avgofMarks = (float)totalMark / numberofMarks;
avgpassedMarks = (float)sumpassedMarks / numberofMarks;
avgfailedMarks = (float)sumfailedMarks / numberofMarks;
printf ("Total of %d students passed with an average of %.1f.\n", numofPasses,avgpassedMarks);
printf ("Total of %d students failed with an average of %.1f.\n", numofFails, avgfailedMarks);
printf ("Highest mark in the group: %.1f\n", highestMark);
printf ("lowest mark in the group: %.1f\n", lowestMark);
printf ("The average of all marks in this group is %.1f.\n", avgofMarks);
printf ("Program Ended.\n");
return 0;
}
The work asks,
In the loop in which marks are being entered, after each entry examine the value of the mark entered:
If it is a pass, add one to the number of passes and add the value of the mark to the sum of passed marks.
If it is a fail, add one to the number of fails and add the value of the mark to the sum of failed marks.
If the value is higher than the highest mark, set highest mark to the value read.
If the value is lower than the lowest mark, set the lowest mark to
the value read. After all the marks are entered and examined, divide
the sums by the corresponding number of marks to get the average and
print the results.
This is my output vs the sample output.

Your code is a mess; let's try to get some things straight here:
If you're not gonna use i in the body of a for loop, no reason to initialize and increment it. Better to use a while.
When you post a question, clear all not-strictly-necessary code from the answer, so that it's easier to help
Instead of making 15 variables, consider using an array or, if you're not gonna use the values later in the program, print the result directly.
Ex.
int a = 10, b = 15; If you wanna print the sum, no reason to save it in a new int sum, just printf("%d", a + b);
Do not request the number of votes outside of a loop, and then loop to verify the value (your first for loop). Consider a DO..WHILE loop instead.
Ex.
do{
scanf("%d", &n);
} while(n <= 0);
//Scan integer and save into n, until you get a positive value
Avoid nesting for loops for no reason, use more if() .. else if() .. if necessary.
It's not the best of practise, but you can also use the continue and break keywords to continue or stop the loops respectively.
Do not use "else" randomly. If you have more conditions to check, leave the if without else. You wanna use else after an if condition if (when the first condition comes back true) you don't want to check the next condition (they will be skipped !)

Related

How do I get this to register -1 as an exit & show the numbered list as starting from 1?

Okay so the prompt was:
"Write a simple program (to demonstrate use of an array) that asks a user to type in numbers and keep typing in numbers until the user enters -1 or the total number of numbers entered reaches 20. Your program will stop asking for new input based on either condition above. Once one of the above conditions are met, the program will output all numbers entered as follows: 1. 888 2. 999 3. 4 …..and so on. Lastly, the program needs to display the sum of all values entered, excluding the -1 used to terminate the user input loop. The array should be used to store the user's inputs, and display them back before the program terminates."
Now, I have most of the prompt completed. It stops at 20 entered variables and displays them and the sum correctly. However, no matter how hard I try, I can't get it to register -1 as an exit. Nor can I get the bulleted list to start from 1. and end at 20. Everything else works just fine.
#include <stdio.h>
#define NUMBER_INPUTS 20
int main(void){
double userInput[NUMBER_INPUTS] = { 0 };
int i = 0;
while (i < NUMBER_INPUTS){
printf("Enter number: \n", i);
scanf("%lf", &userInput[i]);
i++;
}
for(i=0; i<NUMBER_INPUTS; i++)
printf("%i. %.1lf \n", i, userInput[i]);
double total=0;
for(i=0; i<NUMBER_INPUTS; i++)
total+=userInput[i];
printf("Total: %.1lf \n", total);
return 0;
}
This is the code that works just fine. I've tried different do-whiles in different places to register the -1 but it messes up the output list AND doesn't stop the run.
#include <stdio.h>
#define NUMBER_INPUTS 20
int main(void){
double userInput[NUMBER_INPUTS] = { 0 };
int i = 0;
do{
while (i < NUMBER_INPUTS){
printf("Enter number: \n", i);
scanf("%lf", &userInput[i]);
i++;
}
}while (userInput[i] != -1);
for(i=0; i<NUMBER_INPUTS; i++)
printf("%i. %.1lf \n", i, userInput[i]);
double total=0;
for(i=0; i<NUMBER_INPUTS; i++)
total+=userInput[i];
printf("Total: %.1lf \n", total);
return 0;
}
Like this? Just stops at the 20th variable entered. Doesn't matter if I've entered a -1 it just keeps going.
And for the list I attempted to use
i=i+1
to get the list from 1. to 20. to try and bump the i variable up one but for some reason that just shorted the output list to only show 20. and the total? I don't know what I'm doing wrong and would appreciate some input. Thank you.
Be very careful in comparison on floating-point numbers with exact values. (the point of the two links). While double can represent -1 exactly, don't fall into the habit of believing that floating-point numbers can represent any value exactly -- they can't. See: Is floating point math broken? and Why Are Floating Point Numbers Inaccurate?
To stop reading at the input of -1, you need to preserve the value of i (the number of elements) that have a valid double stored when you leave the read loop (that is the number of array elements filled). int n = i; will work (or just use the separate counter n and save i for use as a loop variable). Then in your print loop. for (i = 0; i < n; i++). As you have it, you are attempting to print NUMBER_INPUTS every time. If the user enters -1 after 3 inputs -- that's not going to work.
In order to use any input function correctly, you must validate the return. (this is especially true with scanf with contains many pitfalls for the new C programmer) Otherwise on a matching-failure, your array element will be left indeterminate, character extraction from stdin will cease leaving the offending characters in stdin unread just waiting to bite you again on your next attempted input. Instead -- validate, validate, validate. Lest ye violate Commandment No. 6. Example:
if (scanf ("%lf", &userInput[n]) != 1) { /* validate input */
fputs ("error: invalid double input.\n", stderr);
return 1;
}
Putting the rest together, and giving an example of checking a floating-point value within a tolerance of +/- 1E-5, you could do:
#include <stdio.h>
#define NUMBER_INPUTS 20
int main (void) {
double userInput[NUMBER_INPUTS] = { 0 }, total = 0;
int i = 0, n = 0;
while (n < NUMBER_INPUTS){
fputs ("Enter number: ", stdout);
if (scanf ("%lf", &userInput[n]) != 1) { /* validate input */
fputs ("error: invalid double input.\n", stderr);
return 1;
}
/* check for -1 (with +/- 1E-5 tolerance) */
if (userInput[n] > -1.00001 && userInput[n] < -0.99998)
break;
total += userInput[n];
n++;
}
putchar ('\n');
for(i = 0; i < n; i++)
printf("%d. %.1lf\n", i + 1, userInput[i]);
printf ("\nTotal: %.1lf \n", total);
return 0;
}
Example Use/Output
$ ./bin/total
Enter number: 10
Enter number: 20
Enter number: 30
Enter number: 40
Enter number: 50
Enter number: -1
1. 10.0
2. 20.0
3. 30.0
4. 40.0
5. 50.0
Total: 150.0
Look things over and let me know if you have further questions. You were quite close.
Edit - updated output element indication to i + 1 to meet your requirement of Showing The Numbered List Starting From 1.

Finding the average of 5 numbers and N numbers using only While and do while loop in C

i am really stuck with this been trying to solve it for quite a time now.
i have to write a program where i should input 5 numbers between 1 to 10 and then calculate the average, USING ONLY WHILE LOOP, but it does not have to exit when the number does not meet the requirement. then, i have to write a variation of the same code but this time you can enter all the numbers you want, and when 0 is entered it has to calculate the average and exit
this is where i have gotten so far
#include <stdio.h>
int main(void)
{
int n, i = 1;
float add;
float avg;
do
{
printf("enter the number %d:\n", i++);
scanf("%d", &n);
add = add + n;
} while(n > 0 && n < 11);
avg= (add / 5);
printf("%.1f", avg);
return 0;
}
it will keep asking for numbers after 5 have been entered. and the average is not right anyways
First, you're using nas your while condition variable, but also as the variable to scan the input. If I start your program by scanning 20, for example, your while loop will exit on the first interaction. Use your i variable instead and also increment it every time your loop executes.
do{
...
}while(i <= 5);
Second, if you want only numbers between 1 and 10, then you should write a condition for it. For example:
printf("enter the number %d:\n", i); //do not increment it here!
scanf("%d",&n); //assuming "n" as your variable to scan
if(n > 0 && n < 11){
add += n;
i++; //increment it here instead!
}
Third, initialize your variables in order to not get thrash values
float add = 0;
float avg = 0;
int i = 1;
Finally, assign your result (not mandatory, but since you're using it I'll keep it):
avg = add/5.0f
and display:
printf("%.1f", avg);

Imputing fractions using arrays in C

My program asks the user for a numerator and then a denominator right after (If option 1 is chosen). I am pretty sure i got that part correct.I can not seem to figure out how to display the fraction(s) though when I hit option 2.
This is my code:
#include<stdio.h>
#include<string.h>
typedef struct fraction
{
int numerator, denom;
} fraction; //defined the fraction.
int main()
{//start of program
int z = 0;
int y = 0;
while (1)
{ //start of while loop
int choice;
printf("\nPress 1 to enter a fraction\n");
printf("Press 2 to view the entered fraction\n");
scanf("%d", &choice);
fraction arrFraction[100];
arrFraction[0].numerator = 0;
arrFraction[0].denom = 0;
if (choice == 1) // first option (enter numerator and then denom after)
{
printf("Enter the fraction\n");
scanf("%d", &arrFraction[y].numerator);
scanf("%d", &arrFraction[z].denom);
y++
z++;
}// end of first if statement(to enter the fraction)
if (choice == 2) //to view the entered fractions.
{
printf("\n-----------------------------");
for (int m = 0; m < z; m++)
{
printf(" %d / %d \n", arrFraction[y].numerator/arrFraction[z].denom);
}
printf("\n\n-----------------------------");
} // end of second if statement (to view the fraction entered earlier)
} // end of while loop
system("pause");
return(0);
}
You need to move fraction arrFraction[100]; out of while loop, otherwise, every iteration, there will be a new array.
That said,
printf(" %d / %d \n", arrFraction[y].numerator/arrFraction[z].denom);
is wrong, you're supplying two format specifiers but one argument. This invokes undefined behavior. Your compiler should have warned you.
I believe, what you want instead is
printf(" %d / %d \n", arrFraction[y].numerator, arrFraction[z].denom);
That said, I'm not very convinced with the overall logic. Why do you seem to need an array of 100 elements? If you're only interested in previous record (not records), use only a simple variable, not an array. Besides, you don;t need to have two separate index/ counters anyway. A single index will be able to manage the inputs in much concise and robust way.

How to refine this code and sort the data being read into the array?

I want to write a C program to read an array, calculate the sum of all individual entries, the average, the minimum grade, the maximum grade, and print all of those values. Is this an effective method of sorting? I'm attempting to sort the data values by min and max comparing it as they are input. My compiler also throws a declaration error with all of the float values.
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
float main()
int i;
float grades[10];
float grade;
float sum;
float avg;
float count;
float max;
float min;
{
max =0;
min=0;
printf("Enter your grades (Type <0 and >100 to quit): ");
scanf("%f", &grade);
sum=0;
i=0;
while(grades>0 && i<10)
{grades[i]= grade;
i++;
if(i<10)
{printf("Enter grade, (Type <0 or >100 to quit): ");
scanf("%f", &grade); }}
for (i=0; i < 10; i++)
{if (grades[i] > max)
{
max=grades[i];
}
else if (grades[i] < min)
{
min = grades[i];
}}
count=i;
for(i=0; i<count; i++)
{printf("Grade %d is %f \n", i+1, grades[i]);}
grade=0;
for(i=0;i<count; i++)
{sum= sum + grades[i];}
if(count>0)
{avg=sum/count;}
else
{avg=0;}
printf("The average of the %f grades is %f \n",count, avg);
printf("The Minimum Grade is %f",min);
printf("The Maximum Grade is %f", max);
printf("Count is %f ", count);
printf("Sum is %f", sum);
printf("Average is %f", avg);
}
The very refided code for solving your problem is
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#define GRADE_ARRAY_LEN 10
int main()
{
int i = 0;
double grades[GRADE_ARRAY_LEN];
double grade;
double max;
double min;
while(i<GRADE_ARRAY_LEN)
{
printf("Enter grade, (Type <0 or >100 to quit): ");
if(scanf("%lf", &grade) != 1)
{
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s");
continue;
}
if(grade < 0.0 || grade > 100.0)
{
return 1;
}
else
{
if(i == 0)
{
max = grade;
min = grade;
}
else
{
if(grade > max)
{
max = grade;
}
if(grade < min)
{
min = grade;
}
}
grades[i]= grade;
i++;
}
}
double sum = 0;
for(i=0; i<GRADE_ARRAY_LEN; i++)
{
printf("Grade %d is %lg \n", i+1, grades[i]);
sum+=grades[i];
}
double avg = sum/GRADE_ARRAY_LEN;
printf("The average of the %d grades is %g \n", GRADE_ARRAY_LEN, avg);
printf("The Minimum Grade is %lg\n",min);
printf("The Maximum Grade is %lg\n", max);
printf("Number of grades is %d\n", GRADE_ARRAY_LEN);
printf("Sum is %lg\n", sum);
printf("Average is %lg\n", avg);
return 0;
}
I may have missed something, but i checked it and it works.
The - How it works is a bit long.
First of all the amount of grades you want to enter is fixed and defined in #define GRADE_ARRAY_LEN 10 which lets you easily change the number of grades you want to enter.
Then the programm reads input and checks if the input is double or can be converted to double. This check is simple if(scanf("%lf", &grade) != 1). scanf() returns the number of arguments successfully filled, the format "%lf" means that you want your input argument to be filled as double. So scanf("%lf", &grade) will return only return a value which equals to 1, if you entered a value that can be converted to double.
Now if the input IS NOT double or double or can be converted to double the program askes you to enter an input which is double or can be converted to double. scanf("%s"); is actully needed because when scanf("%lf", &grade) fails there is a newline char left in the input stream, which you have to actually read. If you don't, next scanf("%lf", &grade) will actually take it as an input, and fail again, thus creating an infinite loop.
After the input is successfully filled, it means you have your value of grade. The program checks what value was entered, and exits if the value is smaller than 0 or greater than 100. I did this because printf actually outputs, that the program will exit if the value is smaller than 0 or greater than 100.
If the value of grade is between 0 and 100, then the program checks if it is the first value that was scanned with this if(i == 0). Where i is the number of successfully scanned values. If i == 0 than no values were scanned yet, so max and min must be initialized with this value for max and min to work correctly., because all other values have to be checked against the first value. If i != 0, then the value is checked against max an min, and they are modified in case of need.
After min and max are checked the value is FINALLY added to our array of values and the number of successfully scanned values is increased.
i++;grades[i]= grade;
i++;
NOTE!!!: all the operations above are commited in one single loop, while(i<GRADE_ARRAY_LEN). This ensures that you enter the correct amount of values and get the correct max and min values. You do not actually need extra loops to get correct min and max values.
After the loop, the sum of grades is counted. After that, the avg of grades is counted.
NOTE!!!: You do not need any checks here because the loop ensures that you enter correct amount of elemets.
In the end the results are printed to a command line.
I'll try to point out the main parts that i edited.
First: variable declarations must be inside the brakets of main() and main must return an int, which means your code had this:
float main()
int i;
float grades[10];
float grade;
float sum;
float avg;
float count;
float max;
float min;
{
but it must be like this
int main()
{
int i = 0;
double grades[GRADE_ARRAY_LEN];
double grade;
double max;
double min;
Second: Your code did not check if scanf("%lf", &grade) successfully filled grade. That is wrong because you can actually enter any combination of characters and numbers in command line, but the only correct input is when you enter a number, that can be converted to double. That means you have to check what scanf returns.
Third: max = 0; and min = 0; is not the correct way to initialize max and min values. min=0; is incorrect, because in case of only positive grades, grade will never be smaller than min, thus min will be always 0. The correct way is to initialize min value is with the first correctly read grade from input, so if there is a smaller value is entered, then min can be changed accordinly. The max=0; is incorrect because in case of only negative grades, grade will never be greater than max, thus max will be always 0. The correct way is to initialize max value is with the first correctly read grade from input, so if there is a greater value is entered, then max can be changed accordinly.
Third: As i said above, you do not actually need a separate loop to find max and min values. It can be done inside the loop where data is read. It is not really nececcary, but it's a good practice to do everything you can inside one loop.
Fourth: It is a good practice to define lenght of arrays with fixed length before main function using #define. Quote: "The #define creates a macro, which is the association of an identifier or parameterized identifier with a token string. After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.". That basically means that you add #define GRADE_ARRAY_LEN 10, as shown in code above, before main, and then instead of using 10 as the number of iterations, and number of array elements like double grades[10]; while(i<10); for(i=0;i<10;i++)
you actually use double grades[GRADE_ARRAY_LEN]; while(i<GRADE_ARRAY_LEN); for(i=0;i<GRADE_ARRAY_LEN;i++). The compiler will automaticly substitute GRADE_ARRAY_LEN for 10; Thsi enables you to change 10 for any other number you want (positive of course) only in one place, instead of changing it in several places;
Fifth: printf("Enter grade, (Type <0 or >100 to quit): ") outputs that if you type a value <0 or >100 the program should exit. Considering the input values were not checked at all, this is not happening.
Sixth: while(grades>0 && i<10) is wrong, because grades is an Array, and you can not compare an array to a single number.
Now on to what i actually did to the code to make it work:
1) Moved the var declarations and changed the return value of main
2) Implemented a check for successfull filling of grade by scanf("%lf", &grade).
3) Implemented a program exit in case if input is <0 or >100;. This means the program will actuallly exit if you enter a number smaller than 0 and greater than 100
4) Implemented a #define GRADE_ARRAY_LEN 10 to use as a length of grade array
5) Re-made the loop so it will ask to enter correct input data GRADE_ARRAY_LEN times. Now the program won't continue unless you enter correct input data exactly GRADE_ARRAY_LEN times.
6) Moved the finding of min and max values to the while loop. As said above, you do not actually need a separate loop to find them. Also modified the initialization of min and max
7) Due to changes above, made some changes in the end.
7.1) Changed a little the way sum is counted
Was:
for(i=0;i<count; i++)
{sum= sum + grades[i];}
Now:
double sum = 0;
for(i=0; i<GRADE_ARRAY_LEN; i++)
{
printf("Grade %d is %lg \n", i+1, grades[i]);
sum+=grades[i];
}
7.2) Removed unnecessary check upon calculating avg
Was:
if(count>0)
{avg=sum/count;}
else
{avg=0;}
Now:
double avg = sum/GRADE_ARRAY_LEN;
8) Changed all float values to double. The amount of bytes float allocates for a var is actually dependant on system architecture, where double is actually an Quote: "IEEE 754 double-precision binary floating-point format: binary64".
9) Due to changes above, changed format of the input data from %f to %lf, Changed format of output data from %f to %lg. Now both can work with double.
Replacing this:
double min;
while(i<GRADE_ARRAY_LEN)
{
.......
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s");
With this:
double min;
char c;
while(i<GRADE_ARRAY_LEN)
{
.......
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s", &c);
Should fix the scanf error. The second error is probably because you forgot to copy the closing braket - "}" of main at the very end. What i mean is that you probably have this at the very end:
printf("Average is %lg\n", avg);
return 0;
But!!! it shold be like this
printf("Average is %lg\n", avg);
return 0;
} // !!!!

Numbers precedes number user entered

Ask user to enter a random number between 1 and 100. Then ask how many numbers s/he wants to display that precedes first number s/he enters.
if user enter 9 and wants 3 numbers that precedes 9, your program should display this:
6 7 8 9
I can not finish it.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int endnum, pre;
printf("Enter a random number between 1 and 100: ");
scanf("%d", &endnum);
printf("how many numbers he wants to display that precedes first number you entered: ");
scanf("%d", &pre);
num = endnum - pre;
printf (%d, num+1)
num = num + 1
while (num <= endnum)
return 0;
}
You're pretty close. You've got pre and endnum. You just want to loop from pre to endnum (inclusive), and print out each of them.
You can use a while loop if you want to, but to me this situation lends itself more directly to a for loop. Something like:
for (num = endnum - pre; num <= endnum; ++num)
{
printf("%d ", num);
}
where num is pre-declared as a int.
That's not a bad first attempt, you just need to fix one slight logic problem and some minor syntax things.
As per my original pseudo-code from your previous question, you need to have a loop doing the printing. You also need semicolons for statement terminators, quotes around strings, and to print the correct value. So change:
printf (%d, num+1)
num = num + 1
while (num <= endnum)
into:
do {
printf ("%d ", num);
num = num + 1;
} while (num <= endnum);
In addition, you'll also need to define num the same way you've defined endnum and pre.

Resources