averaging numbers in text file

B

Bill Reed

I'm trying to add numbers from a text file and find the average. The
numbers in the file are:

25 50 75 100

I expect the result to be 62.50 but I get 85.00. I've twiddled with
the condition expression of the for statement but apparently I have no
idea what I'm doing. Post-increment or pre-increment seems to make no
difference. Any help appreciated.

/* avg.c : find the average of n integers
in a text file */
#include <stdio.h>

int main() {
int num, i;
float sum;

for(i = 0; i != '\n'; i++)
{
scanf("%d", &num);
sum += num;
}
printf("The average is %.2f\n", sum/i);
return 0;
}

Thanks,
Bill
 
B

Bertrand Mollinier Toublet

Bill said:
I'm trying to add numbers from a text file and find the average. The
numbers in the file are:

25 50 75 100

I expect the result to be 62.50 but I get 85.00. I've twiddled with
the condition expression of the for statement but apparently I have no
idea what I'm doing. Post-increment or pre-increment seems to make no
difference. Any help appreciated.

/* avg.c : find the average of n integers
in a text file */
#include <stdio.h>

int main() {
int num, i;
float sum;

for(i = 0; i != '\n'; i++)
{
scanf("%d", &num);
sum += num;
}
printf("The average is %.2f\n", sum/i);
return 0;
}
Assuming an architecture with ASCII character set, we have '\n' == 10.
Thus, for i going from 0 to 3, you scan the four numbers in your file,
so that sum equals 250. For the next 6 attempts, the scanf execution
fails to interpret anything, and, I suppose, num is unchanged, so that
you actually add 6 * 100 = 600 to your sum.

At the end of the for loop, we thus have sum == 850. So that your
average is 850 / 10 = 85.

That i != '\n' *has* to be a huge brainfart, 'cause else, you are hereby
sentenced to not write a line of C code until you have read, re-read and
re-re-read the K&R 2 !

That said, please note that:
1) you really want to use doubles instead of floats. The possible gain
in program footprint is far outweigh by the loss in precision when you
prefer to use floats.
2) for regular counters (happilly hopping from 0 to some arbitrary N),
you should prefer to use the size_t type.
3) only Dan Pop has enough clues to use scanf directly. The rest of us
prefer to use fgets or variants thereof (I _do_ like ggets), with
possibly sscanf or strto*.
4) in your printf, sum/i actually had type float, while your printf
conversion specifier (%f) expects a double.
 
B

Bertrand Mollinier Toublet

Although, please note that this is a probable explanation, but nothing
you can rely on. Remember that when you have undefined behaviour in your
program (sun being uninitialized, which I missed, is an example),
*anything* can happen, and it generally doesn't bring much to try and
explain what happened.

The typical example of "Don't explain" is anything along the lines of

i = i++ + ++i;

You can spend hours saying "the good result should be this or that
because this or that", but it is all moot: the expression invokes
undefined behaviour, is illegal, and is allowed to yield any result it
wants including letting DEMONs (those missile-mounted nuclear warheads)
fly out of the local NOSE (the operating center to launch the warheads).
 
G

Giuseppe

I'm trying to add numbers from a text file and find the average. The
numbers in the file are:

25 50 75 100

I expect the result to be 62.50 but I get 85.00.

with scanf would be fine use switch + goto

#include <stdio.h>

int main()
{int num=0, i, c;
float sum=0;/* here num=0, sum=0 */

printf("Inserisci i numeri: "); fflush(stdout);
for(i=0;;)
{switch(scanf("%d[^\n]", &num))
{case 1: sum += num;
++i;
if((c=getchar())==EOF || c=='\n')
goto label;
else ungetc(c, stdin);
break;
case 0:/*if scanf meets one letter (a,b,c..) or EOF end*/
case EOF: goto label;
}
}
label:
printf("The average is %.2f\n", (float) (sum/i) );
return 0;
}
 
G

Giuseppe

#include <stdio.h>

int main()
{int num=0, i, c;
float sum=0;/* here num=0, sum=0 */

printf("Inserisci i numeri: "); fflush(stdout);
for(i=0;;)
{switch(scanf("%d[^\n]", &num))
{case 1: sum += num;
++i;
if((c=getchar())==EOF || c=='\n')
goto label;
else ungetc(c, stdin);
break;
case 0:/*if scanf meets one letter (a,b,c..) or EOF end*/
case EOF: goto label;
}
}
label: i==0?++i: 0;
printf("The average is %.2f\n", (float) (sum/i) );
return 0;
}
 
B

Bill Reed

So far I have this but I need to do more reading.

/* avg.c : find the average of n integers
in a text file */
#include <stdio.h>

int main() {
int num, i;
double sum = 0;
FILE *fptr1;
char file1[] = "avg.txt";
fptr1 = fopen(file1, "r");

YOu need to check that the file was opened successfully.
If 'fopen()' returned NULL, it was not, and you should
not try to read from the file.

By 'opened successfully' do you mean that the file exits? When I use
the command:

avg < avg.txt

if avg.txt does not exist the system lets me know. Or are there other
problems I might encounter?
You're using feof() incorrectly. It doesn't indicate
end of file until *after* an attempt to read *past*
end of file.


Actually, it does. It waits for *you* to do something.
'scanf()' takes input from 'standard input', which is
typically a 'console' on systems that have one. If you
want to read from a file, use 'fscanf()' or 'fgets()'
or 'fgetc()' etc.

BTW which book(s) are you reading? Perhaps you need
better one(s).

I looked up feof() in "Teach Yourself C in 24 Hours". I purchased K&R
2 yesterday. The former books description of the function seems
comparable to K&R 2 but his program examples don't appear to lend
themselves to my application. Probably I just need to read and think
about it some more.

Bill
 
B

Bill Reed

I'm trying to add numbers from a text file and find the average. The
numbers in the file are:

25 50 75 100

I expect the result to be 62.50 but I get 85.00.

with scanf would be fine use switch + goto

#include <stdio.h>

int main()
{int num=0, i, c;
float sum=0;/* here num=0, sum=0 */

printf("Inserisci i numeri: "); fflush(stdout);
for(i=0;;)
{switch(scanf("%d[^\n]", &num))
{case 1: sum += num;
++i;
if((c=getchar())==EOF || c=='\n')
goto label;
else ungetc(c, stdin);
break;
case 0:/*if scanf meets one letter (a,b,c..) or EOF end*/
case EOF: goto label;
}
}
label:
printf("The average is %.2f\n", (float) (sum/i) );
return 0;
}

This is interesting. If I remove the printf() and fflush() line the
result is exactly what I was looking for. As mentioned in another post
I should probably declare sum as a double so it doesn't need to be
converted later. This is very different from anything I was
considering as a solution. Thanks.

Bill
 
M

Morris Dovey

Bill said:
if avg.txt does not exist the system lets me know. Or are there other
problems I might encounter?

Bill...

On my system fopen() can fail even when the file exists if I
don't have the requisite file permission(s).
Probably I just need to read and think about it some more.

(A winning strategy! 8^)
 
G

Giuseppe

I'm trying to add numbers from a text file and find the average. The
numbers in the file are:

25 50 75 100

I expect the result to be 62.50 but I get 85.00.

with scanf would be fine use switch + goto

#include <stdio.h>

int main()
{int num=0, i, c;
float sum=0;/* here num=0, sum=0 */

printf("Inserisci i numeri: "); fflush(stdout);
for(i=0;;)
{switch(scanf("%d[^\n]", &num))
{case 1: sum += num;
++i;
if((c=getchar())==EOF || c=='\n')
goto label;
else ungetc(c, stdin);
break;
case 0:/*if scanf meets one letter (a,b,c..) or EOF end*/
case EOF: goto label;
}
}
label:
printf("The average is %.2f\n", (float) (sum/i) );
return 0;
}

This is interesting. If I remove the printf() and fflush() line the
result is exactly what I was looking for. As mentioned in another post
I should probably declare sum as a double so it doesn't need to be
converted later. This is very different from anything I was
considering as a solution. Thanks.

Bill
please you note that if there is not input => case 0 => i=0 => sum/i
ERROR
 
G

Giuseppe

#include <stdio.h>

int main()
{int num=0, i, c;
float sum=0;/* here num=0, sum=0 */

printf("Inserisci i numeri: "); fflush(stdout);
for(i=0;;)
{switch(scanf("%d[^\n]", &num))
{case 1: sum += num;
++i;
if((c=getchar())==EOF || c=='\n')
goto label;
else ungetc(c, stdin);
break;
case 0:/*if scanf meets one letter (a,b,c..) or EOF end*/
case EOF: goto label;
}
}
label: i==0?++i: 0;
printf("The average is %.2f\n", (float) (sum/i) );
printf("The average is %.2f\n", (double) (sum/i) );
^^^^^^^^
Why for scanf %f is float and for printf %f is double?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top