write error

B

Bill Cunningham

I get this file to compile with a warning on line 20. Somewhere for some
reason it must crash at the place I indicated. I want to take a buffer of
text and write in to a text file.

#include <stdio.h>
#include <stdlib.h>
#define BUF 20

int main(int argc, char **argv)
{
if (argc != 2) {
fputs("write usage error\n", stderr);
exit(1);
}
FILE *fp;
char *a;
printf("enter text:\n\n");
fgets(a, BUF, stdin); /* here or next line */
if ((fp = fopen(argv[1], "w")) == NULL) {
perror(argv[1]);
exit(1);
}
while ((a = fgets(NULL, BUF, fp)) == EOF)
printf("saved to file\n");
fclose(fp);
return 0;
}
 
B

Ben Bacarisse

Bill Cunningham said:
I get this file to compile with a warning on line 20. Somewhere for some
reason it must crash at the place I indicated. I want to take a buffer of
text and write in to a text file.

#include <stdio.h>
#include <stdlib.h>
#define BUF 20

int main(int argc, char **argv)
{
if (argc != 2) {
fputs("write usage error\n", stderr);
exit(1);
}
FILE *fp;
char *a;
printf("enter text:\n\n");
fgets(a, BUF, stdin); /* here or next line */

'a' is a pointer that you have not set. Using it in almost any way is
an error, but asking fgets to put data there is disastrous.

The best way to use fegts is with a character array:

char a[BUF];

will do the trick, though it is neater to write fgets like this:

fgets(a, sizeof a, stdin);
if ((fp = fopen(argv[1], "w")) == NULL) {
perror(argv[1]);
exit(1);
}
while ((a = fgets(NULL, BUF, fp)) == EOF)

This is even more peculiar. The first argument to fgets tell is where
to put the data it reads. You need to provide it a place to store
what it reads.
 
B

Bill Cunningham

Ben Bacarisse said:
Bill Cunningham said:
I get this file to compile with a warning on line 20. Somewhere for
some
reason it must crash at the place I indicated. I want to take a buffer of
text and write in to a text file.

#include <stdio.h>
#include <stdlib.h>
#define BUF 20

int main(int argc, char **argv)
{
if (argc != 2) {
fputs("write usage error\n", stderr);
exit(1);
}
FILE *fp;
char *a;
printf("enter text:\n\n");
fgets(a, BUF, stdin); /* here or next line */

'a' is a pointer that you have not set. Using it in almost any way is
an error, but asking fgets to put data there is disastrous.

The best way to use fegts is with a character array:

char a[BUF];

will do the trick, though it is neater to write fgets like this:

fgets(a, sizeof a, stdin);

Ok I see. The first parameter to fgets that I read was char *s and I
interpreted that as a string. Not in array form.
if ((fp = fopen(argv[1], "w")) == NULL) {
perror(argv[1]);
exit(1);
}
while ((a = fgets(NULL, BUF, fp)) == EOF)

This is even more peculiar. The first argument to fgets tell is where
to put the data it reads. You need to provide it a place to store
what it reads.
printf("saved to file\n");
fclose(fp);
return 0;
}
 
B

Bill Cunningham

Richard Heathfield said:
Ben Bacarisse said:


And while he's fixing that, he can be fixing the comparison too: fgets
is not one of those functions that returns EOF. Even if it were, the
proper comparison would be != rather than ==. And why is he trying to
read from a file open for output?


And why this, when he's reading (or trying to read) /from/ a file?

I want to write into a buffer of size BUF from char *s. fgets first
parameter. The filename is supposed to be provided on the command line as
argv[1]. The text entered is via fgets into char *a. Or I guess should be
char a[BUF]. Doesn't fgets return a char * ? That's where I got confused and
tried to take that a and compare. My man pages in the linux machine I write
C on didn't clearly tell me the return value for a error with fgets.

Bill
 
B

Bill Cunningham

I'm trying to read from the stream stdin.
I want to write into a buffer of size BUF from char *s. fgets first
parameter. The filename is supposed to be provided on the command line as
argv[1]. The text entered is via fgets into char *a. Or I guess should be
char a[BUF]. Doesn't fgets return a char * ? That's where I got confused
and tried to take that a and compare. My man pages in the linux machine I
write C on didn't clearly tell me the return value for a error with fgets.

Bill
 
B

Bill Cunningham

What does your man page say?

The text is in between the bottom of the first page and top of the next
so it's not clear to read. I also though I saw EOF on that line and that's
clearly an error if s or NULL is returned.

Bill
 
P

Phil Carmody

Richard Heathfield said:
Ben Bacarisse said:


And while he's fixing that, he can be fixing the comparison too: fgets
is not one of those functions that returns EOF. Even if it were, the
proper comparison would be != rather than ==. And why is he trying to
read from a file open for output?


And why this, when he's reading (or trying to read) /from/ a file?

YHBT.

Phil
 
D

Dik T. Winter

> > if ((fp = fopen(argv[1], "w")) == NULL) {
> > perror(argv[1]);
> > exit(1);
> > }
> > while ((a = fgets(NULL, BUF, fp)) == EOF)
>
> This is even more peculiar. The first argument to fgets tell is where
> to put the data it reads. You need to provide it a place to store
> what it reads.

It is more peculiar than that. Why does he attempt to read from a file
that has been opened for writing?
 
B

Bill Cunningham

No, it says "Reading stops after an EOF or a newline", which is true,
and clearly not an error. Do not confuse the concept of an EOF
condition (end of file has been encountered) with the concept of a
return value.

It does. That's where I was confused. Using fgets to write from is truly
an oversight on my part. I haven't used it for so long I forgot that arrays
and not pointers are the preferred pass to parameter one.

Bill
 
K

Keith Thompson

pete said:
Richard Heathfield wrote: [...]
No, it says "Reading stops after an EOF or a newline", which is
true, and clearly not an error. Do not confuse the concept of an EOF
condition (end of file has been encountered) with the concept of a
return value.

The most confusing thing about the concept of an EOF condition is that
there's no such thing. EOF is a macro. End-of-file is a condition.
The man page is confusing the concept of end-of-file with
the concept of EOF.

I think it's merely not being sufficiently clear about the fact that
fgets reads characters (as if) by calling fgetc.

fgets() reads in at most one less than size characters from
stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline. If a newline is read,
it is stored into the buffer. A '\0' is stored after the last
character in the buffer.

Reading stops after fgetc() returns the value EOF.
 
N

Nobody

The most confusing thing about the concept of an EOF condition is that
there's no such thing. EOF is a macro. End-of-file is a condition.

"EOF" doesn't only refer to the C macro with that name. It can just be an
abbreviation for "end of file".

Although using it in that way in a manpage which covers both fgetc() and
fgets() is probably unwise.
 
K

Kaz Kylheku

pete said:
Richard Heathfield wrote: [...]
No, it says "Reading stops after an EOF or a newline", which is
true, and clearly not an error. Do not confuse the concept of an EOF
condition (end of file has been encountered) with the concept of a
return value.

The most confusing thing about the concept of an EOF condition is that
there's no such thing. EOF is a macro. End-of-file is a condition.
The man page is confusing the concept of end-of-file with
the concept of EOF.

I think it's merely not being sufficiently clear about the fact that
fgets reads characters (as if) by calling fgetc.

fgets() reads in at most one less than size characters from
stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline. If a newline is read,
it is stored into the buffer. A '\0' is stored after the last
character in the buffer.

On one system I have here, the above text is is found in a page dated
1993-04-04, attributed as being from the ``Linux Programmer's Manual''.

The project which resulted in the current C library didn't even exist in 1993!

So this is very obsolete text, and not the official documentation which
accompanies the (library part of) the implementation.

That would be the GNU Info manual, accessed by ``info libc''.
 
K

Keith Thompson

Kaz Kylheku said:
pete said:
Richard Heathfield wrote: [...]
No, it says "Reading stops after an EOF or a newline", which is
true, and clearly not an error. Do not confuse the concept of an EOF
condition (end of file has been encountered) with the concept of a
return value.

The most confusing thing about the concept of an EOF condition is that
there's no such thing. EOF is a macro. End-of-file is a condition.
The man page is confusing the concept of end-of-file with
the concept of EOF.

I think it's merely not being sufficiently clear about the fact that
fgets reads characters (as if) by calling fgetc.

fgets() reads in at most one less than size characters from
stream and stores them into the buffer pointed to by s.
Reading stops after an EOF or a newline. If a newline is read,
it is stored into the buffer. A '\0' is stored after the last
character in the buffer.

On one system I have here, the above text is is found in a page dated
1993-04-04, attributed as being from the ``Linux Programmer's Manual''.

The project which resulted in the current C library didn't even
exist in 1993!

So this is very obsolete text, and not the official documentation which
accompanies the (library part of) the implementation.

On my system (Ubuntu with recent updates), the same text is found in
a page dated 2008-08-06, part of the Linux man-pages project (release
3.15; the most recent release, 3.22, is less than a month old).
That would be the GNU Info manual, accessed by ``info libc''.

That documentation for fgets doesn't mention EOF:

-- Function: char * fgets (char *S, int COUNT, FILE *STREAM)
The `fgets' function reads characters from the stream STREAM up to
and including a newline character and stores them in the string S,
adding a null character to mark the end of the string. You must
supply COUNT characters worth of space in S, but the number of
characters read is at most COUNT - 1. The extra character space
is used to hold the null character at the end of the string.

If the system is already at end of file when you call `fgets', then
the contents of the array S are unchanged and a null pointer is
returned. A null pointer is also returned if a read error occurs.
Otherwise, the return value is the pointer S.

Note that this doesn't explicitly say what happens if the of the
input file doesn't end in a newline character, though I suppose
you could infer the behavior from what's written. The C standard
doesn't specify this, but the glibc documentation probably should.

(I'm aware that there are arguments regarding whether man pages or
info documents are, or should be, considered the best source of
information; I don't propose to get into those arguments here.)
 
R

Richard Bos

Kaz Kylheku said:
On one system I have here, the above text is is found in a page dated
1993-04-04, attributed as being from the ``Linux Programmer's Manual''.

The project which resulted in the current C library didn't even exist in 1993!

Only for a very strict interpretation of "the project". The project
which resulted in the relevant part of the Standard is the previous
Standard, which certainly did exist in 1993 and which was, for that
part, transferred unchanged into the new one.
So this is very obsolete text, and not the official documentation which
accompanies the (library part of) the implementation.

That would be the GNU Info manual, accessed by ``info libc''.

That's irrelevant (as well as bletcherous). The document that requires
fgets() to work _as if_ calling fgetc() is the Standard. Ganuck may
choose to do something completely different behind the scenes, but if it
doesn't work out as if it complies with the Standard, it ain't C.

Richard
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top