read and write columns

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

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
 
R

rahul

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;
What exactly do you mean? input + (linput / count) or (input +
linput) / count. Do you see a divide by zero problem here? Since input
and linput are define as double, your mean equals infinity.
if ((fpw=fopen("data","w"))!=EOF);
if ((fpr=fopen("data","r"))!=EOF);
May be next time you should remember fopen returns FILE * and the
error checking is done against NULL.
So if ((fpw = fopen("data", "w")) != NULL);
But heck; even now it is meaning-less(that ;, if you didn't notice).
Check for NULL and then do nothing - just proceed with the code.
if ((fscanf(fpr,input,linput,mean))==0;
Again, check for error and do nothing. And this won't compile on any
known compiler(missing parenthesis).
fprintf(fpw,"%d\t%d\t%d\n",input,input+linput,mean);
}
input, input + linput are doubles. mean is a double and equals
infinity. %d, if you have a look at the doc, is meant for signed
integers.
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.
I don't know but it looks like to me that you created this mess on
purpose. There are better ways to have fun if that is what you are
trying to have over here.
 
R

rahul

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) {
Though it is legal, naming the parameter the same as your function
name is not a good practice.
 
R

Ron Ford

Barry Schwarz said:


Good spot, Barry. I missed that completely.


Just a thought here - Bill Cunningham is a self-confessed slow learner, so
it might be quicker for us and more productive for him if we just point
out the *first* mistake. Maybe over time BC will begin to understand that
he's not going to get help with problem B for so long as his code
continues to exhibit problem A, and he might - just *might* - work out
that eliminating problem A from all his code is therefore a productive
thing for him to do.


I think this idiom is largely unnecessary:

If every char you put has to be tested for EOF, then you have a deficient
OS. I gave windows 40 gigs today. It prompts me annoyingly for lack of
hog space.

That the C programming language must be constarined to the average clicker
is a distortion.
 
R

Ron Ford

Ron Ford said:



It isn't an idiom. It's just a bug.

When I have to do IO with C, I use safegets, but I don't think that that is
what you mean.

My point was that my OS doesn't say nay to me on a char basis.

I'm curious what you mean.
 
R

Ron Ford

Ron Ford said:


The fopen function never returns EOF, ever. Since EOF is an int, and since
fopen returns a FILE *, testing the return value of fopen against EOF is
completely pointless. (In this case, the semicolon makes it doubly
pointless.)

I see. What I was getting at was more like:
putchar(anything)!=EOF ....

The test against anything for a putchar call seems prudent but ends up
being a lot of extra keystrokes and code.

EOF has alwyas been negative one on my impkementation.
--
 
R

Richard Tobin

Ron Ford said:
I see. What I was getting at was more like:
putchar(anything)!=EOF ....

The test against anything for a putchar call seems prudent but ends up
being a lot of extra keystrokes and code.

Depending on the application, it may be reasonable just to use
ferror() to test the stream at the end of the output, or at other
natural times such as before reading input. But be sure to also check
the return value of fclose(): buffering both within the stdio library
and in the operating system may mean that errors are not detected
until the file is closed.
EOF has alwyas been negative one on my impkementation.

EOF must be a negative int.

-- Richard
 
R

Richard Bos

Ron Ford said:
I see. What I was getting at was more like:
putchar(anything)!=EOF ....

You may have tried to get at that, but since it wasn't in the OP's
posted code, it would be hard to reach it.
The test against anything for a putchar call seems prudent but ends up
being a lot of extra keystrokes and code.

A lot? Rather an exaggeration, isn't it? If you do it right, that check
for EOF will double as your loop termination condition, which you would
have needed anyway.
EOF has alwyas been negative one on my impkementation.

That's as may be, and it is indeed by far the most common value, but all
the Standard demands is that EOF is negative. Besides, EOF is both
clearer, and only a single character longer, than -1.

Richard
 
N

Nick Keighley

    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.

WHAT ARE YOU TRYING TO DO
 
K

Keith Thompson

Bill Cunningham 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.

Look up the word "increment" in your C textbook.

I thought you were going to run your code through "indent" before
posting it.

You have no "main" function.

The code you posted doesn't compile. Did you even try compiling it
before posting?

You attempt to open the same file, "data", for writing and reading,
using two separate streams. This makes no sense.

You have 3 if statements. You don't do anything in any of them. Just
how do you think an if statement works?

Why are you comparing the result of fopen() to EOF? Read the
documentation for fopen(). Don't guess.

You're calling fscanf() with four arguments: a FILE* (good) and three
doubles. Read the documentation for fscanf. For the umpteenth time,
don't guess.

You haven't said what the code is supposed to do. For the umpteenth
time, state the problem you're trying to solve. If you haven't done
that, writing even a single line of code is a waste of time.

This appears to be similar in intent to something that was discussed
at length in another thread, but I'm not going to assume that there's
any correlation; you never offered a decent problem definition in that
thread either.

In the absence of any problem definition, here's a correct program
that meets all the requirements you've stated:

int main(void)
{
}

If you can tell us what functionality is missing from that program,
*maybe* we can start to help you.

But I doubt it.

I honestly think you need to go back a few steps. Pick a simpler
problem to solve. Define the problem clearly in plain English. Then,
and only then, try to write a program to solve the problem. Never
write a call to a library function without first understanding what
arguments the function expects, what result it returns, and what each
and every argument and result means. This requires reading the
documentation.

Get a copy of K&R2 if you don't already have one. Start at the
beginning and work your way through it. Do all the exercises.
 
J

John J. Smith

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 */
 
B

Bill Cunningham

I honestly think you need to go back a few steps. Pick a simpler
problem to solve. Define the problem clearly in plain English. Then,
and only then, try to write a program to solve the problem. Never
write a call to a library function without first understanding what
arguments the function expects, what result it returns, and what each
and every argument and result means. This requires reading the
documentation.

Get a copy of K&R2 if you don't already have one. Start at the
beginning and work your way through it. Do all the exercises.

I have kandr2 but I use a little pocket reference here at the desk. It
says you can use "t" for text with fopen. That's not the standard I guess.

Now I think I've caught onto a little more but with fopen's mode. "w"
will create a file but would "w+" or "r+" ? I will try two stream one to
create a text file the other to read and write from. I still don't get the
increment part. If someone would just show me that part and not a long
program with structs and the like then I think I can catch on quicker. I
would understand one more thing.

Bill
 
K

Keith Thompson

Bill Cunningham said:
I have kandr2 but I use a little pocket reference here at the desk. It
says you can use "t" for text with fopen. That's not the standard I guess.

Your pocket reference is lying to you. Stop using it. Consider
throwing it away.

(That's a little harsh; it's probably referring to some particular
implementation that happens to accept "t", which is a valid extension.
But if it doesn't tell you that "t" is non-portable, it's leading you
astray.)

K&R2 is an excellent book on C. It's more of a tutorial than a
reference manual, though there is a reference section at the end.

I've advised you to start at the beginning of K&R2 and work through
it. You can ignore my advice if you like, but then I can't help you.
Now I think I've caught onto a little more but with fopen's mode. "w"
will create a file but would "w+" or "r+" ?

Why are you asking us?

Look. It. Up.
I will try two stream one to
create a text file the other to read and write from.

You want two streams: one to read from the existing file, and the
other to create and write to the new file. There's no reason to read
and write to the same stream.

This is based on some reasonable assumptions about what you're trying
to do, since you have refused to tell us. You need to define the
****ing problem before you worry about fopen modes and incrementing
counters.
I still don't get the
increment part. If someone would just show me that part and not a long
program with structs and the like then I think I can catch on quicker. I
would understand one more thing.

count++;

Hope that helps.
 
V

vippstar

I have kandr2 but I use a little pocket reference here at the desk. It
says you can use "t" for text with fopen. That's not the standard I guess.
read this post: <wSE5k.40580$lE3.20244@trnddc05>
Here, let me help you get this right: 't' is non-standard. I hope from
now on you won't have to *guess*, you will *know* it is not standard.
 
B

Bill Cunningham

I've advised you to start at the beginning of K&R2 and work through
it. You can ignore my advice if you like, but then I can't help you.

Ok I guess that's simple begin at chapter one. Maybe do a chapter a day.

Thanks Keith for all your help. If I get confused or something I'll come to
the group.

Bill
 
S

santosh

pete said:
John J. Smith wrote:


That would have been funnier this way:

union bar {
FILE *fi;
FILE *fo;
FILE *fum;
};

It would be even funnier this way:

union bar {
FILE *fee;
FILE *fi;
FILE *fo;
FILE *fum;
};
 
B

Barry Schwarz

Ok I guess that's simple begin at chapter one. Maybe do a chapter a day.

No, don't do a chapter a day! Stay on a chapter until you understand
everything in it and you have done all the exercises. It would
probably be good to not do more than one exercise a day. And don't
start the next exercise until you have finished the current one.


Remove del for email
 
B

Bill Cunningham

Richard Heathfield said:
Even a sentence a day can be quite a challenge. K&R2's information density
is simply colossal.

What about your book Richard? "C Unleashed" I have a copy of it too. In
your opinion would it be better for me personally to learn from your book
first anyway? It's much larger but might be more digestable.

Bill
 
R

Ron Ford

You may have tried to get at that, but since it wasn't in the OP's
posted code, it would be hard to reach it.


A lot? Rather an exaggeration, isn't it? If you do it right, that check
for EOF will double as your loop termination condition, which you would
have needed anyway.


Out of n tests against EOF, how many do you think were unnecessary?
That's as may be, and it is indeed by far the most common value, but all
the Standard demands is that EOF is negative. Besides, EOF is both
clearer, and only a single character longer, than -1.

My impkemenation is sometimes more clever than the monkey on the keyboard.
 

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,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top