How can I average these numbers correctly in C? - arrays

I wrote some code that reads numbers from another file and it's supposed to input the numbers from the file and output the average. The numbers I input are (1,2,3,4,5,6,7,8,9,10). But the average it's giving me is 2,4,6,8.10.
How do I correct this?
Code:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *myFile;
myFile = fopen("numbers.txt", "r");
int numberArray[10];
int i;
int sum = 0;
int n = 0;
int avg = 0;
if (myFile == NULL){
printf("Error Reading File\n");
exit (0);
}
for (i = 0; i < 10; i++){
fscanf(myFile, "%d,", &numberArray[i] );
}
for (i = 0; i < 10; i++){
sum += n;
i++;
avg = (sum / i);
printf("Average is: %d\n\n", numberArray[i]);
}
fclose(myFile);
return 0;
}

"...The numbers I input are (1,2,3,4,5,6,7,8,9,10) Instead of the average its giving me 2,4,6,8.10. How do I correct this?..."
Focusing on only the final loop, a few items to consider that will address this issue, and a few others:
Depending on values of numerator and divisor the average might not be exactly correct due to integer division rounding error. if this is an issue for you, the first code snippet addresses it. If not, the following snippets address only the skipping array elements...
As covered, the following code segment in the original post increments i twice, once in the for() loop, then later in the i++ statement. The following addresses each of these, also corrects assignment statements, all with with comments...
float sum = 0.0;//to avoid integer division rounding error, use a floating point type
float ave = 0.0;
for (i = 0; i < 10; i++){
//sum += n;//n does not represent the values strore
sum += (float)numberArray[i];
//i++;//not needed, i is incremented in for loop
avg = (sum/i);
printf("Average is: %f\n\n", ave);
// ^ changed from d to f,
// and numberArray[i] to ave
}
Note, if the effects of integer division are acceptable for your purposes, then use the following:
int sum = 0;
int ave = 0;
for (i = 0; i < 10; i++){
sum += numberArray[i];
avg = (sum/i);
printf("Average is: %d\n\n", ave);
}
And, if outputting only the final result is required (rather than all of the intermediate values), move the last two statements to just after the for loop:
for (i = 0; i < 10; i++){
sum += numberArray[i];
}
avg = (sum/i);
printf("Average is: %d\n\n", ave);
"Is it possible to place the given average back into the file? "
The original statement: myFile = fopen("numbers.txt", "r"); opened the file for read only. But placing the resulting average back into the file requires reopening the file for append and using fputs():
...
fclose(myFile);
//add the following...
char sAve[20] = {0};
myFile = fopen("numbers.txt", "a");
if(myFile)
{
sprintf(sAve, "\nAverage is: %f0.6", ave)
fputs(sAve, myFile);
fclose(myFile);
}
return 0;
}

In this for loop, you increment i twice, once inside the for()-statement, once at i++.
for (i = 0; i < 10; i++){
sum += n;
i++;
avg = (sum/ i);
printf("Average is: %d\n\n", numberArray[i]);
}
If I understand correctly, the second increment should be removed. Also your intended output is not quite clear to me. If this does not solve it, maybe specify your question.
If you just want the average of all the numbers first add them all together:
for(i=0; i<10; i++){
sum+=numberArray[i];
}
Then divide by the number of elements
avg = sum/10;
Then you can printout the average:
printf("Average is: %d\n", avg);
I think this is what your code intends to do.

Related

C program to read 'n' numbers and find out the sum of odd valued digits of each number and print them

i am new to programing, i want to know that how we can find the odd digits in a number.
the condition in this program is we should only use concept of arrays.I tried a code for this as follows:
#include <stdio.h>
int main()
{
int A[50],i,x,y,n,sum=0;
scanf("%d",&n);
printf("the value is %d\n",n);
for(i=0;i<n;i++)
scanf("%d",&A[i]);
for(i=0;i<n;i++){
x=A[i]%10;
if(x%2!=0)
sum=sum+x;
A[i]=A[i]/10;
printf("the sum of odd numbers is %d\n",sum);
}
return 0;
}
but in this the code is checking for only one digit of the first number in the loop and then next time it is going to check the digit of second number.
so, i need to write a code to check all digits in the number and then it goes to next number and check all digits and should continue the same process in the loop.So, for this how should i modify my code?
You were missing a loop that would iterate through every digit of A[i] - the inner while loop below,
#include <stdio.h>
int main()
{
int A[50], i, x, y, n, sum=0;
printf("How many numbers will you input?\n");
scanf("%d",&n);
printf("the value is %d\n",n);
for(i=0; i<n; i++) {
scanf("%d",&A[i]);
}
for(i=0; i<n; i++) {
sum = 0;
while (A[i] > 0) {
x = A[i]%10;
if(x%2 != 0) {
sum = sum + x;
}
A[i] = A[i]/10;
}
printf("the sum of odd numbers is %d\n",sum);
}
return 0;
}
The exact algorithm for iterating through each digit in a nice form can be found in this post - although for a different language. Here, apart from the while loop, you also need to reset the sum each time unless you want a cumulative sum over all provided numbers.
Note that I changed the formatting a bit - more space, extra braces, and a message about what you're prompting the user to input.
int temp;
int sum = 0;
temp = number;
do {
lastDigit = temp % 10;
temp = temp / 10;
sum += (lastDigit %2 != 0) ? lastDigit : 0;
} while(temp > 0);

For loop "<" vs "<=" print format issues in program

I am learning C on my own with a book and I cannot for the life of me figure out how to solve this exercise. I'm obviously looking at it in the wrong way or something. Here is an explanation below.
Listed below are some functions and the main function at the bottom. This program is compiled to generate a certain number of random numbers and determine the min and the max of the random numbers. If you copy and paste this code, you will see how it works. Anyways, an exercise asks me to go to the function "prn_random_numbers()" and change the for loop from "for (i = 1; i < k; ++i)" to for (i = 2; i <= k; ++i). This causes the first line format to print incorrectly. The exercise is to further modify the program in the body of the for loop to get the output to be formatted correctly.
To sum it up, the "prn_random_numbers()" function is written to print out 5 random numbers before moving to the next line. Hence the" i % 5" if statement. Now, for some reason, when you make the slight adjustment to the for loop, as the exercise asks above, it causes the first line to only print 4 numbers before moving to the next line. I have tried a number of things, including trying to force it to print the 5th number, but it only duplicated one of the random numbers. I even tried "i % 4" to see if it would print 4 numbers for each row, but it only prints 3 numbers for the first row instead of 4! So it always prints one less number on the first line than it is supposed to. I have n clue why it is doing that and the book does not give an exercise. Do you have any idea?
Bear with me if you think this is a stupid question. I am just learning on my own and I want to make sure I have a good foundation and understand everything as I learn it, before moving forward. I appreciate any help or advice!
prn_random_numbers(k) /* print k random numbers */
int k;
{
int i, r, smallest, biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for (i = 1; i < k; ++i)
{
if (i % 5 == 0)
printf("\n");
r = rand();
smallest = min(r, smallest);
biggest = max(r, biggest);
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}
int main()
{
int n;
printf("Some random numbers are to be printed.\n");
printf("How many would you like to see? ");
scanf("%d", &n);
while (n < 1)
{
printf("ERROR! Please enter a positive integer.\n");
printf("How many would you like to see? ");
scanf("%d", &n);
}
prn_random_numbers(n);
return (EXIT_SUCCESS);
}
the following proposed code:
properly initializes the random number generator
cleanly compiles
properly checks for and handles errors
performs the desired functionality
avoids having to list instructions twice
follows the axiom: Only one statement per line and (at most) one variable declaration per statement.
does not use undefined functions like: max() and min()
and now the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void prn_random_numbers(int k)
{
int count = 1;
int r;
int smallest;
int biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for ( int i = 2; i <= k; i++, count++)
{
if (count % 5 == 0)
{
count = 0;
printf("\n");
}
r = rand();
smallest = (r < smallest)? r : smallest;
biggest = (r > biggest)? r : biggest;
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}
int main( void )
{
int n;
srand( (unsigned)time( NULL ) );
do
{
printf("Please enter a positive integer, greater than 0.\n");
printf("How many would you like to see? ");
if( scanf("%d", &n) != 1 )
{
fprintf( stderr, "scanf for number of random numbers failed\n" );
exit( EXIT_FAILURE );
}
} while( n < 1 );
prn_random_numbers(n);
// in modern C, if the returned value from `main()` is 0 then no `return 0;` statement needed
}
a typical run, no input problems is:
Please enter a positive integer, greater than 0.
How many would you like to see? 20
98697066 2110217332 1247184349 421403769 1643589269
1440322693 985220171 1915371488 1920726601 1637143133
2070012356 541419813 1708523311 1237437366 1058236022
926434075 1422865093 2113527574 626328197 1618571881
20 random numbers printed.
Minimum: 98697066
Maximum: 2113527574
Try to use a debugger to solve your problem, it's easy to use and really helpfull :)
SOLUTION:
Your i variable don't count the number of numbers because it is initialize at 1 (in the for statement), so you need to declare a new variable to count properly.
If you have still a problem:
void prn_random_numbers(int k)
{
int count = 1;
int i, r, smallest, biggest;
r = smallest = biggest = rand();
printf("\n%12d", r);
for (i = 2; i <= k; i++, count++) {
if (count % 5 == 0) {
count = 0;
printf("\n");
}
r = rand();
smallest = min(r, smallest);
biggest = max(r, biggest);
printf("%12d", r);
}
printf("\n\n%d random numbers printed.\n", k);
printf("Minimum:%12d\nMaximum:%12d\n", smallest, biggest);
}

Having Trouble Counting and Summing Integers from Text File

Sorry for being such a novice.
For this question I used C language, and the libraries stdlio.h and stdlib.h.
Question
So a question is asking me to:
Open a text file named 'numbers.txt' in read mode. This text file
has 6 integers in it.
Read the 6 integers from that text file using a loop.
Calculate and display the total and average of those 6 integers.
The text file 'numbers.txt' holds the integers: 5, 10, 15, 20, 25.
Here's my code:
FILE *n;
n = fopen("numbers.txt", "r");
int a, num, sum = 0;
float avg;
for (a = 0; a < 6; a++) {
fscanf(n, "%d", &num);
sum = sum + num;
}
avg = sum / (a - 1);
printf("Sum = %d\nAverage = %.2f\n\n", sum, avg);
fclose(n);
Another variation of the question is that I need to use a while loop to read the integers in the text file.
Here's my code for that:
FILE *n;
n = fopen("numbers.txt", "r");
int a = 0, num, sum = 0;
float avg;
while (fscanf(n, "%d", &num) != EOF) {
fscanf(n, "%d", &num);
sum = sum + num;
a++;
}
avg = sum / a;
printf("Sum = %d\nAverage = %.2f\n\n", sum, avg);
fclose(n);
Problem
When I run each of the above programs, I expect this output:
Sum = 75
Average = 15.00
However I get this instead (for the first code):
Sum = 100
Average 20.00
And this (for the second code):
Sum = 55
Average = 18.00
How am I able to get the correct output from both of these programs?
Again I apologise for how basic this question is. Nonetheless, any help would be appreciated.
In the first one, you tried to read one-to many numbers, but since there were only 5 numbers, the last number was added twice to your sum, so you ended up adding an extra 25 to the sum to get 100.
In the second code, after reading the last number, the end of the file was reached, so your code did not get the opportunity to add the last read number, so you missed adding 25 to your sum.
You were much closer with your first code, just change the for-loop to only iterate 5 times
Here is my observation,
Case 2 : The problem is here in below two line of code
while (fscanf(n, "%d", &num) != EOF) { /* this is fine, scanf() stored read int into num */
fscanf(n, "%d", &num); /* this is not needed as overwrites previous num, just remove it */
/* some code */
}
Also this
avg = sum / a;
doesn't get you expected result as sum/a results in integer but you are assigning it to avg which is float. One way to overcome this is to do typecasting like below
avg = (float)(sum / a);
Sample code :
int main(void) {
FILE *n;
n = fopen("numbers.txt", "r"); /* always do error handling to make more robust code */
if(n == 0) {
#TODO error handling */
}
int a = 0, num, sum = 0;
float avg;
while (fscanf(n,"%d", &num) != EOF) {
//fscanf(n, "%d", &num);// remove this
sum = sum + num;
a++;
}
avg = (float)(sum / a);// typecast it
printf("Sum = %d\nAverage = %.2f\n\n", sum, avg);
fclose(n);
return 0;
}
Case 1 : Here
for (a = 0; a < 6; a++)
rotating loop fixed number of times may not be a problem for now but it creates issue when you don't know in advance how many integer number file having. so better rotate loop until EOF. For e.g
for (a = 0; ; a++) {
if(fscanf(n, "%d", &num) == 1) /* compare with return value */
sum = sum + num;
else
break;
}

Regarding scanf and many values to input

So I'm trying to solve this http://www.codeabbey.com/index/task_view/sum-in-loop and I have 45 random numbers to input. I'm coding using C so I want to use the scanf function. The problem is that since it's 45 numbers (which are separated by spaces) what I want to do is copy paste the values so that the program can solve them from an array. Should I do it like this:
int x [45];
scanf("%d %d....(x42) %d",&x,&x,...(x42),&x);
or is there a more efficient way of doing this? (I hope there is T_T)
You need not (and you should not) write a single format string containing 45(or whatever) format specifier, following 45 pointers.
You need to use a loop.
Example:
for loop with an array, will hold the supplied operands, too
int x[45] = {0};
int sum = 0;
for (int i = 0; i < 45; i++) //style supported over C99
{
scanf("%d", &x[i]);
sum += x[i];
}
printf("sum = %d\n", sum);
for loop without an array, won't hold the operands, only result
int x = 0;
int sum = 0;
for (int i = 0; i < 45; i++) //style supported over C99
{
scanf("%d", &x);
sum += x;
}
printf("sum = %d\n", sum);

Can't get standard deviation to work in C

I tried everything to get standard deviation to work.
I'm trying to make a program that gets grades of students (count decided by user) and it calculates the mean of the grades and also the standard deviation. It calculates the mean fine but for standard deviation it gives "7712160851427328.00"
#include <stdio.h>
int main(){
int i;
int j;
int count;
int grade = 0;
int grades[5] = {0}; //Init
int sum = 0;
float deviation_sum;
float mean;
float standard_deviation;
printf("Give Count: ");
scanf("%d", &count);
for(i = 0; i < count; i++){
printf("Give %d grade: ", (i+1));
scanf("%d", &grade);
switch(grade){
case 0:
grades[0]++;
break;
case 1:
grades[1]++;
break;
case 2:
grades[2]++;
break;
case 3:
grades[3]++;
break;
case 4:
grades[4]++;
break;
case 5:
grades[5]++;
}
sum += grade;
}
mean = sum/count;
printf("mean: %.2f \n", mean);
for(i = 0; i <= 5; i++){
while(grades[i] == 0){
i++;
}
for(j = 0; j < grades[i]; j++){
deviation_sum += (i-mean)*(i-mean);
printf("%d,%d\n",i,j);
}
}
standard_deviation = sqrt(deviation_sum /count - 1);
printf("deviation: %.2f\n", standard_deviation);
}
I think the problem is in the last for loop just can't figure it out.
You'll have to initilize deviation_sum to zero. Otherwise it takes garbage value as its initial value
Your mean calculation will fail as you are doing integer division, and this will then make the subsequent std dev calculation incorrect.
Change:
mean = sum/count;
to
mean = (float)sum/count;
so that the division is performed using floating point arithmetic. You might also want to print the value of mean at this point to check that it looks reasonable.
Also this
standard_deviation = sqrt(deviation_sum /count - 1);
shall be
standard_deviation = sqrt(deviation_sum / (count - 1));
Please see here for the background.
First of all, avoid this type of construct (i could cause array access out-of-bounds):
for(i = 0; i <= 5; i++){
while(grades[i] == 0){
i++;
}
Use if instead of while and use continue to loop over again.
For correcting the error you are getting, do following changes in your code (I am just giving you hints)
1. Use typecasting where necessary
2. Monitor variables (especially array indices) for proper bounds
3. When using functions like sqrt, do check for positivity of the argument otherwise you may face Domain ERROR.
4. Always remember to initialize variables when required.
I would also suggest a task for you:
Try removing your switch with a simpler logic.

Resources