Bill said:
I don't think I can do this without some help or hints. Here is the
code
I have.
#include <stdio.h>
#include <stdlib.h>
double input(double input) {
int count=0,div=0;
double mean=0,linput=0;
FILE *fpr, *fpw;
mean=input+linput/count;
if ((fpw=fopen("data","w"))!=EOF);
if ((fpr=fopen("data","r"))!=EOF);
if ((fscanf(fpr,input,linput,mean))==0;
fprintf(fpw,"%d\t%d\t%d\n",input,input+linput,mean);
}
It's very much incomplete. I have two stream open one for reading and one
for writing but the count that I have been speaking of, I don't know how
to increment it.
Bill,
For this task you need to use a union. Find below a small program that
demonstrates the following:
(1) how to use structs, unions, and enums.
(2) how to open a text file for input.
(3) how to read text representations of floating point numbers from a
text file.
(4) how to open a text file for output.
(5) how to calculate sum and mean from the numbers acquired in step (3).
(6) how to write text representations of floating point numbers calculated
in step (5) to a text file.
with the this input (data.txt),
10.50
10.25
10.00
10.75
11.00
the following output (out.txt) is produced
10.50 10.50 10.50
10.25 20.75 10.38
10.00 30.75 10.25
10.75 41.50 10.38
11.00 52.50 10.50
Enjoy.
/* begin coltxt.c (released to public domain) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static const char *datafile = "data.txt";
static const char *outfile = "out.txt";
struct foo {
float number;
float sum;
float mean;
};
union bar {
FILE *fi;
FILE *fo;
};
enum baz {
P_OK = 0,
P_EOF = -1,
P_OPEN = -2,
P_READ = -3,
P_WRITE = -4,
P_TOOLONG = -5,
P_TOOSHORT = -6,
P_BADNUMBER = -7,
P_RANGE = -8,
P_NOMEM = -9,
P_LASTERR = -10
};
char *my_strerr(int);
int fgetf(float *, FILE *);
#define getf(x) fgetf((x), stdin)
int main(void)
{
struct foo *foo;
union bar bar;
int ch, chp;
size_t i, j, nlines;
if((bar.fi = fopen(datafile, "r")) == NULL) {
fprintf(stderr, "%s: %s.\n", my_strerr(P_OPEN), datafile);
return EXIT_FAILURE;
}
nlines = 0; chp = '\n';
for(;
{
ch = fgetc(bar.fi);
if(ch == '\n' || (ch == EOF && chp != '\n'))
nlines++;
if((chp = ch) == EOF)
break;
}
if(nlines == 0) {
fprintf(stderr, "File %s contains 0 lines.\n", datafile);
fclose(bar.fi);
return EXIT_FAILURE;
}
if((foo = malloc(sizeof * foo * nlines)) == NULL) {
fprintf(stderr, "%s.\n", my_strerr(P_NOMEM));
fclose(bar.fi);
return EXIT_FAILURE;
}
fprintf(stdout,
"Reading %lu lines from %s, please wait...\n",
(unsigned long)nlines, datafile);
rewind(bar.fi);
for(i = j = 0; i < nlines; i++) {
float f; int res;
struct foo *p;
if((res = fgetf(&f, bar.fi)) != 0) {
if(res == P_EOF)
break;
else if(res == P_TOOSHORT) /* ignore emty lines */
continue;
fprintf(stderr,
"Problem reading line %lu from %s: %s.\n",
(unsigned long)i, datafile, my_strerr(res));
free(foo);
fclose(bar.fi);
return EXIT_FAILURE;
}
p = foo + j++;
p->number = f;
p->sum = p->mean = 0.f;
}
if(j < nlines) {
struct foo * tmp = realloc(foo, sizeof * tmp * j);
if(tmp)
foo = tmp;
nlines = j;
}
fclose(bar.fi);
if((bar.fo = fopen(outfile, "w")) == NULL) {
fprintf(stderr, "%s: %s.\n", my_strerr(P_OPEN), datafile);
free(foo);
return EXIT_FAILURE;
}
fprintf(stdout,
"Writing %lu lines to %s, please wait...\n",
(unsigned long)nlines, outfile);
for(i = 0; i < nlines; i++) {
for(j = 0; j <= i; j++)
foo
.sum += foo[j].number;
foo.mean = foo.sum / (i+1);
if(fprintf(bar.fo, "%.2f %.2f %.2f\n",
foo.number, foo.sum, foo.mean) < 0) {
fprintf(stderr, "%s: %s\n", my_strerr(P_WRITE), outfile);
free(foo);
fclose(bar.fo);
return EXIT_FAILURE;
}
}
fprintf(stdout, "All done!\n");
free(foo);
fclose(bar.fo);
return EXIT_SUCCESS;
}
/*
* getf(): read and interpret single line from f as float
*/
int fgetf(float *res, FILE *f)
{
char buf[2048], *p, *q;
size_t len;
float result;
if(fgets(buf, sizeof buf, f) != buf) {
if(feof(f)) return P_EOF;
else return P_READ;
}
p = buf; len = strlen(p);
if(len && *(p + len - 1) != '\n') {
int ch = fgetc(f);
if(ch != EOF) {
while(ch != '\n' && ch != EOF)
ch = fgetc(f);
return P_TOOLONG;
}
}
else
*(p + --len) = '\0';
if(len == 0)
return P_TOOSHORT;
p = buf + len - 1;
while(*p == ' ' || *p == '\t') {
*p-- = '\0'; len--;
}
p = buf;
while(*p == ' ' || *p == '\t') {
p++; len--;
}
if(len == 0)
return P_TOOSHORT;
errno = 0;
result = strtod(p, &q);
if(*q != '\0')
return P_BADNUMBER;
if(errno == ERANGE)
return P_RANGE;
if(res)
*res = result;
return 0;
}
char *my_strerr(int errnum)
{
static char *rr[] = {
"No error",
"EOF",
"Error opening file",
"Read error",
"Write error",
"Line too long",
"Line too short",
"Not a valid number",
"Number out of range",
"Out of memory",
"Unknown error",
};
if(errnum < P_LASTERR || errnum > 0) errnum = P_LASTERR;
return rr[-errnum];
}
/* end coltxt.c */