Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #76375 > unrolled thread

EOF issue

Started byAlla _ <modelling.data@gmail.com>
First post2015-11-18 01:03 -0800
Last post2015-11-18 21:09 +0000
Articles 16 — 10 participants

Back to article view | Back to comp.lang.c


Contents

  EOF issue Alla _ <modelling.data@gmail.com> - 2015-11-18 01:03 -0800
    Re: EOF issue Ian Collins <ian-news@hotmail.com> - 2015-11-18 22:55 +1300
      Re: EOF issue Alla _ <modelling.data@gmail.com> - 2015-11-18 02:54 -0800
        Re: EOF issue "Osmium" <r124c4u102@comcast.net> - 2015-11-18 06:48 -0600
          Re: EOF issue Lőrinczy Zsigmond <nospam@for.me> - 2015-11-18 16:35 +0100
            Re: EOF issue "Osmium" <r124c4u102@comcast.net> - 2015-11-18 12:58 -0600
        Re: EOF issue Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 16:31 +0000
    Re: EOF issue Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 11:00 +0000
      Re: EOF issue Alla _ <modelling.data@gmail.com> - 2015-11-18 07:31 -0800
        Re: EOF issue Richard Heathfield <rjh@cpax.org.uk> - 2015-11-18 17:34 +0000
          Re: EOF issue Keith Thompson <kst-u@mib.org> - 2015-11-20 17:57 -0800
        Re: EOF issue Barry Schwarz <schwarzb@dqel.com> - 2015-11-18 11:44 -0800
          Re: EOF issue alla.rashitova@gmail.com - 2015-11-19 00:47 -0800
            Re: EOF issue Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-19 05:56 -0800
              Re: EOF issue Richard Heathfield <rjh@cpax.org.uk> - 2015-11-19 16:22 +0000
        Re: EOF issue Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-18 21:09 +0000

#76375 — EOF issue

FromAlla _ <modelling.data@gmail.com>
Date2015-11-18 01:03 -0800
SubjectEOF issue
Message-ID<39e3aac5-5b96-4a07-9078-4a6c0207e0df@googlegroups.com>
Hello!

EOF means that the input has reached the end of the file. I think
I understand how it might work when I use some external file (for
example, txt one) in the program. But how does it work when referred
to a function within a program. Below is a program that counts
words, lines and characters, but the loop never seem to terminate when
I run the program (program for K&R).

/** Program to count lines, words, characters
in a word **/

#include <stdio.h>

#define IN  1 //inside a word
#define OUT 0 //outside a word

int main(void)
{
    int c, nl, nw, nc, state;
   
    state = OUT;
    nl = nw = nc = 0;
   
    while ((c = getchar()) != EOF)
    {
        nc++;
       
        if (c == '\n')
            nl++;
       
        if (c ==' ' || c == '\n' || c == '\t')
            state = OUT;
       
        else if (state == OUT)
        {
            state = IN;
            nw++;
        }
    }
   
    printf("%d %d %d\n", nl, nw, nc);
   
    return 0;
}

Thank you! 

[toc] | [next] | [standalone]


#76377

FromIan Collins <ian-news@hotmail.com>
Date2015-11-18 22:55 +1300
Message-ID<db307lFk8g8U1@mid.individual.net>
In reply to#76375
Alla _ wrote:
> Hello!
>
> EOF means that the input has reached the end of the file. I think
> I understand how it might work when I use some external file (for
> example, txt one) in the program. But how does it work when referred
> to a function within a program.

Are you referring to this line

     while ((c = getchar()) != EOF)

?

This will loop until getchar() sees an end of file condition.  This will 
happen either

a) if you run the program and type stuff in, when you hit the end of 
file character (ctrl-D on Unix, ctrl-Z on Windows)

or

b) if you pipe a file to the program, when the end of the file is seen. 
  For example, if I call your code a.c:

cat a.c | ./a.out
33 82 529

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#76382

FromAlla _ <modelling.data@gmail.com>
Date2015-11-18 02:54 -0800
Message-ID<6b87a6bb-ffc0-4a4b-b0dd-c1906fb60c00@googlegroups.com>
In reply to#76377
> Are you referring to this line
> 
>      while ((c = getchar()) != EOF)
> 
> ?
> 
> This will loop until getchar() sees an end of file condition.  This will 
> happen either
> 
> a) if you run the program and type stuff in, when you hit the end of 
> file character (ctrl-D on Unix, ctrl-Z on Windows)
> 
Thank you for your reply. Yes, I am referring to this part 
while ((c = getchar()) != EOF). 

I have tried both Ctrl-D and Ctrl-Z on my Mac. Ctrl-D didn't have 
any effect; Ctrl-Z stopped the program. 
Therefore, I am not sure how authors suggest to use this program, given
no piping is implied (it's just the beginning of the book).

[toc] | [prev] | [next] | [standalone]


#76393

From"Osmium" <r124c4u102@comcast.net>
Date2015-11-18 06:48 -0600
Message-ID<db3adaFo5fdU1@mid.individual.net>
In reply to#76382
"Alla _" <modelling.data@gmail.com> wrote in message 
news:6b87a6bb-ffc0-4a4b-b0dd-c1906fb60c00@googlegroups.com...
>
>> Are you referring to this line
>>
>>      while ((c = getchar()) != EOF)
>>
>> ?
>>
>> This will loop until getchar() sees an end of file condition.  This will
>> happen either
>>
>> a) if you run the program and type stuff in, when you hit the end of
>> file character (ctrl-D on Unix, ctrl-Z on Windows)
>>
> Thank you for your reply. Yes, I am referring to this part
> while ((c = getchar()) != EOF).
>
> I have tried both Ctrl-D and Ctrl-Z on my Mac. Ctrl-D didn't have
> any effect; Ctrl-Z stopped the program.
> Therefore, I am not sure how authors suggest to use this program, given
> no piping is implied (it's just the beginning of the book). 

[toc] | [prev] | [next] | [standalone]


#76407

FromLőrinczy Zsigmond <nospam@for.me>
Date2015-11-18 16:35 +0100
Message-ID<n2i5sj$gvl$1@speranza.aioe.org>
In reply to#76393
>> I have tried both Ctrl-D and Ctrl-Z on my Mac. Ctrl-D didn't have
>> any effect; Ctrl-Z stopped the program.
>> Therefore, I am not sure how authors suggest to use this program, given
>> no piping is implied (it's just the beginning of the book).

Ctrl+D might not work if the line is not empty:

ABC^D -- nothing special
^D    -- EOF

(here ^D means Ctrl+D)

[toc] | [prev] | [next] | [standalone]


#76440

From"Osmium" <r124c4u102@comcast.net>
Date2015-11-18 12:58 -0600
Message-ID<db402hFts9rU1@mid.individual.net>
In reply to#76407
"Lőrinczy Zsigmond" wrote:

>>> I have tried both Ctrl-D and Ctrl-Z on my Mac. Ctrl-D didn't have
>>> any effect; Ctrl-Z stopped the program.
>>> Therefore, I am not sure how authors suggest to use this program, given
>>> no piping is implied (it's just the beginning of the book).
>
> Ctrl+D might not work if the line is not empty:
>
> ABC^D -- nothing special
> ^D    -- EOF
>
> (here ^D means Ctrl+D)

BINGO!  That happens on Windows and ^z. 

[toc] | [prev] | [next] | [standalone]


#76413

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-18 16:31 +0000
Message-ID<87twojw9p5.fsf@bsb.me.uk>
In reply to#76382
Alla _ <modelling.data@gmail.com> writes:

>> Are you referring to this line
>> 
>>      while ((c = getchar()) != EOF)
>> 
>> ?
>> 
>> This will loop until getchar() sees an end of file condition.  This will 
>> happen either
>> 
>> a) if you run the program and type stuff in, when you hit the end of 
>> file character (ctrl-D on Unix, ctrl-Z on Windows)
>> 
> Thank you for your reply. Yes, I am referring to this part 
> while ((c = getchar()) != EOF). 
>
> I have tried both Ctrl-D and Ctrl-Z on my Mac. Ctrl-D didn't have 
> any effect; Ctrl-Z stopped the program.

I'd expect Ctrl-D to work but you might have to type it at the start of
a line or type it twice in a row.  I've just borrowed a Mac and it does
indeed work like that.  Of course, you program might have a bug that's
preventing it from doing what you expect when getchar() returns EOF.

> Therefore, I am not sure how authors suggest to use this program, given
> no piping is implied (it's just the beginning of the book).

The program does not care and neither does the book!  If your system
won't let you terminate an input stream, use a pipe or a file
redirection or a "here" document if your shell permits them.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76383

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-18 11:00 +0000
Message-ID<87poz7y3km.fsf@bsb.me.uk>
In reply to#76375
Alla _ <modelling.data@gmail.com> writes:

> EOF means that the input has reached the end of the file.

No.  EOF is just a number -- a negative number.  On many systems it's -1
but you can't be sure about that.  It has no intrinsic meaning other
than being a number, but there is an agreement that many C library
functions will return EOF to signal the something has gone wrong.  Even
when dealing with files, a returned value of EOF does not always mean
that the problem was that there was no more data.  For example, fclose
returns EOF when the file can't be closed, and sscanf can return EOF
even though it does no input at all.  IO error in general (being unable
to do output for example) are also usualyl indicated by returning EOF.

It may seem like a pedantic point, but it really helps to read program
as the right level of abstraction.  When you see if (.... == EOF) you
can't conclude anything about testing for end-of-file.  You must read it
like any other comparison -- some value (probably the result of a
function call) is being tested to see if it equal to the number EOF.  To
know what that means, you need to read about the specific function to
see how it uses EOF.

> I think
> I understand how it might work when I use some external file (for
> example, txt one) in the program. But how does it work when referred
> to a function within a program.

I am wondering what this means.  Can you write a fragment of code that
shows a case where you do understand it?  I can't think of any cases
where it's not going to be refer to a function within the program.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#76406

FromAlla _ <modelling.data@gmail.com>
Date2015-11-18 07:31 -0800
Message-ID<fff30e38-fe45-48c7-81e7-f2713fbd67d0@googlegroups.com>
In reply to#76383
On Wednesday, November 18, 2015 at 3:01:08 PM UTC+4, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> 
> > EOF means that the input has reached the end of the file.
> 
> No.  EOF is just a number -- a negative number.  On many systems it's -1
> but you can't be sure about that.  It has no intrinsic meaning other
> than being a number, but there is an agreement that many C library
> functions will return EOF to signal the something has gone wrong.  Even
> when dealing with files, a returned value of EOF does not always mean
> that the problem was that there was no more data.  For example, fclose
> returns EOF when the file can't be closed, and sscanf can return EOF
> even though it does no input at all.  IO error in general (being unable
> to do output for example) are also usualyl indicated by returning EOF.
> 
> It may seem like a pedantic point, but it really helps to read program
> as the right level of abstraction.  When you see if (.... == EOF) you
> can't conclude anything about testing for end-of-file.  You must read it
> like any other comparison -- some value (probably the result of a
> function call) is being tested to see if it equal to the number EOF.  To
> know what that means, you need to read about the specific function to
> see how it uses EOF.
>
I see. Therefore, do I understand correctly that instead of putting EOF
in the while loop, the loop should also have another terminating condition,
for example:

   while ((c = getchar()) != EOF || (c = getchar()) != '\n' ) 

Otherwise, I don't see how authors suggested to stop the loop. When
I run this program, it doesn't work.
> 
> I am wondering what this means.  Can you write a fragment of code that
> shows a case where you do understand it?  I can't think of any cases
> where it's not going to be refer to a function within the program.

I might have misinterpreted (unfortunately, as it still happens to me) what
I have read about over a week ago. When I get back to that part, and if
I still have the same erroneous (as I deduct from the way you asked 
that question :) ) idea, I will post the reference. 

[toc] | [prev] | [next] | [standalone]


#76430

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-11-18 17:34 +0000
Message-ID<n2icmg$8s1$1@dont-email.me>
In reply to#76406
On 18/11/15 15:31, Alla _ wrote:
> [...] do I understand correctly that instead of putting EOF
> in the while loop, the loop should also have another terminating condition,
> for example:
>
>     while ((c = getchar()) != EOF || (c = getchar()) != '\n' )

No, you just need to find out how to tell your terminal that you've 
finished typing.

while((c = getchar()) != EOF)

is correct.

When you've finished typing your input, press ENTER (because text input 
is line-oriented, so you need to send the end-of-line character '\n' 
which you do by pressing ENTER), and then hit ^D (Control-D). That 
should work on the Mac. If it doesn't, by all means do it a second time. 
If *that* doesn't work, then ask a Mac programmer.

To get you started, here is an echo program:

#include <stdio.h>

int main(void)
{
   int c = 0;
   while((c = getchar()) != EOF)
   {
     putchar(c);
   }
   return 0;
}

This will copy the program's input to its output, and it has the 
advantage of being very, very simple (and correct).

Use it (compile and run it) to figure out how to signal an end-of-file 
condition from standard input (as outlined above).

Once you've learned how to do that:

(a) don't forget, and
(b) use that information when writing the program you were actually 
trying to write in the first place.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#76705

FromKeith Thompson <kst-u@mib.org>
Date2015-11-20 17:57 -0800
Message-ID<ln1tbkcdxb.fsf@kst-u.example.com>
In reply to#76430
Richard Heathfield <rjh@cpax.org.uk> writes:
[...]
> To get you started, here is an echo program:
>
> #include <stdio.h>
>
> int main(void)
> {
>    int c = 0;
>    while((c = getchar()) != EOF)
>    {
>      putchar(c);
>    }
>    return 0;
> }
>
> This will copy the program's input to its output, and it has the 
> advantage of being very, very simple (and correct).

And it's a simple version of "cat", not "echo".

> Use it (compile and run it) to figure out how to signal an end-of-file 
> condition from standard input (as outlined above).

On Unix-like systems (including Mac OSX), end-of-file while reading from
a keyboard is signalled by typing Ctrl-D once at the beginning of a line
(i.e., either as the first input or immediately after typing <Enter>)
*or* by typing Ctrl-D twice other than at the beginning of a line.  The
latter is uncommon; you usually want complete lines of input.

You can also provide input in batch mode.  For example, you can provide
your program with a single line of input by typing:

    echo hello | ./your_program

or multiple lines like this:

    ( echo "line one" ; echo "line two" ) | ./your_program

or

    printf "line one\nline two\n" | ./your_program

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#76450

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-11-18 11:44 -0800
Message-ID<fbkp4b1a72900fhfkcob0f4ks2k4aimt77@4ax.com>
In reply to#76406
On Wed, 18 Nov 2015 07:31:46 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:

>I see. Therefore, do I understand correctly that instead of putting EOF
>in the while loop, the loop should also have another terminating condition,
>for example:
>
>   while ((c = getchar()) != EOF || (c = getchar()) != '\n' ) 

You are not thinking things through.  

If you look at the code you typed in from K&R, you will see that it
actually processes '\n' characters to count the number of lines.  If
you are counting lines, why would you want to stop after the first?

And then there is that terrible code.  
     The first operand of the || operator calls getchar and assigns
the result to c.
     c is compared to EOF.
     When the result is not equal, the expression evaluates to true
and the || operator determines there is no need to evaluate the second
expression.  You enter the body of the loop.
     When the results are equal, getchar has failed to provide a
character from the input stream.  The normal reason for this is end of
file but others have pointed out this is not always the case.  Assume
it is since this is a beginner's exercise.
     Since the comparison evaluated to false, the || operator
determines that the second operand needs to be evaluated.  This also
calls getchar.  WHAT?  After finding end of file you decide to read
another character!?  What comes after end of file?

There is nothing in the two analyses above that you could not do
yourself.  Using a shotgun or throwing darts at a board are terrible
approaches to programming.  There are no substitutes for analysis and
attention to detail.  While coding is the fun part of the job, it is
only a small part and should definitely not be the first.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#76497

Fromalla.rashitova@gmail.com
Date2015-11-19 00:47 -0800
Message-ID<f6e02ca4-3911-467a-bd59-a0f5b8d09450@googlegroups.com>
In reply to#76450
On Wednesday, November 18, 2015 at 11:44:25 PM UTC+4, Barry Schwarz wrote:
> On Wed, 18 Nov 2015 07:31:46 -0800 (PST), Alla _
> <modelling.data@gmail.com> wrote:
> 
> >I see. Therefore, do I understand correctly that instead of putting EOF
> >in the while loop, the loop should also have another terminating condition,
> >for example:
> >
> >   while ((c = getchar()) != EOF || (c = getchar()) != '\n' ) 
> 
> You are not thinking things through.  
> 
> If you look at the code you typed in from K&R, you will see that it
> actually processes '\n' characters to count the number of lines.  If
> you are counting lines, why would you want to stop after the first?
> 
> And then there is that terrible code.  
>      The first operand of the || operator calls getchar and assigns
> the result to c.
>      c is compared to EOF.
>      When the result is not equal, the expression evaluates to true
> and the || operator determines there is no need to evaluate the second
> expression.  You enter the body of the loop.
>      When the results are equal, getchar has failed to provide a
> character from the input stream.  The normal reason for this is end of
> file but others have pointed out this is not always the case.  Assume
> it is since this is a beginner's exercise.
>      Since the comparison evaluated to false, the || operator
> determines that the second operand needs to be evaluated.  This also
> calls getchar.  WHAT?  After finding end of file you decide to read
> another character!?  What comes after end of file?
> 
It is clear now, and I see my big mistake. Thank you very much for
taking time for this explanation. I have written it down under the name
"HUGE MISTAKE", therefore I hope I have learned it.

> There is nothing in the two analyses above that you could not do
> yourself.  Using a shotgun or throwing darts at a board are terrible
> approaches to programming.  There are no substitutes for analysis and
> attention to detail.  While coding is the fun part of the job, it is
> only a small part and should definitely not be the first.

I know, understand and agree with you. I do still fail in this, because
there are many times, still, when I get "writer's block" (what's the 
equivalent for programming?) when I just don't see even such obvious 
things. I am working on it, though indeed not thoroughly enough, I guess. 

[toc] | [prev] | [next] | [standalone]


#76514

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-11-19 05:56 -0800
Message-ID<7ede3c63-52ec-4b9c-ad21-2ba1359aad5a@googlegroups.com>
In reply to#76497
On Thursday, November 19, 2015 at 8:48:15 AM UTC, _Alla wrote:
> 
> > There is nothing in the two analyses above that you could not do
> > yourself.  Using a shotgun or throwing darts at a board are terrible
> > approaches to programming.  There are no substitutes for analysis and
> > attention to detail.  While coding is the fun part of the job, it is
> > only a small part and should definitely not be the first.
> 
> I know, understand and agree with you. I do still fail in this, because
> there are many times, still, when I get "writer's block" (what's the 
> equivalent for programming?) when I just don't see even such obvious 
> things. I am working on it, though indeed not thoroughly enough, I guess.
>
The way to get good is to write lots of code. Which means getting graphics
going as soon as possible - no one is motivated by command line payroll
databases unless they are hooked up to real money.

However, as far as EOF goes, write  a C character-reading loop like this

FILE *fp = /* stdin or open a file for reading with fopen */
int ch;

while( (ch = fgetc(fp)) != EOF)
{
    if( /* maybe you want to terminate before EOF */)
       break;
}

pretty much every professional programmer either uses that pattern
or is so familiar with it that it's second nature to read.

[toc] | [prev] | [next] | [standalone]


#76534

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-11-19 16:22 +0000
Message-ID<n2ksr9$jrm$1@dont-email.me>
In reply to#76514
On 19/11/15 14:05, Stefan Ram wrote:

<snip>

>    Why do the professionals not check that »fp« is nonzero
>    between »fopen« and »fgetc«?

They do.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#76458

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-11-18 21:09 +0000
Message-ID<87oaervwte.fsf@bsb.me.uk>
In reply to#76406
Alla _ <modelling.data@gmail.com> writes:

> On Wednesday, November 18, 2015 at 3:01:08 PM UTC+4, Ben Bacarisse wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> 
>> > EOF means that the input has reached the end of the file.
>> 
>> No.  EOF is just a number -- a negative number.  On many systems it's -1
>> but you can't be sure about that.  It has no intrinsic meaning other
>> than being a number, but there is an agreement that many C library
>> functions will return EOF to signal that something has gone wrong.  Even
>> when dealing with files, a returned value of EOF does not always mean
>> that the problem was that there was no more data.  For example, fclose
>> returns EOF when the file can't be closed, and sscanf can return EOF
>> even though it does no input at all.  IO errors in general (being unable
>> to do output, for example) are also usually indicated by returning EOF.
>> 
>> It may seem like a pedantic point, but it really helps to read programs
>> at the right level of abstraction.  When you see if (.... == EOF) you
>> can't conclude anything about testing for end-of-file.  You must read it
>> like any other comparison -- some value (probably the result of a
>> function call) is being tested to see if it equal to the number EOF.  To
>> know what that means, you need to read about the specific function to
>> see how it uses EOF.
>>
> I see. Therefore, do I understand correctly that instead of putting EOF
> in the while loop, the loop should also have another terminating
> condition,

I don't see howyou get that from what I wrote.  I've seen a few errors
in what I wrote, but nothing that could lead you to thinking that there
must be some other terminating condition.  For one thing, you write
several loops before that all used

  while ((c = getchar()) != EOF) ...

or am I miss remembering?  getchar() returns the number EOF when
something has gone wrong and no character could be read.  It's therefore
entirely correct to loop while getchar does not return EOF.

> for example:
>
>    while ((c = getchar()) != EOF || (c = getchar()) != '\n' )

This is wrong in so many ways!  You don't need it and it does not do
what you think it does.  I wrote a long text about why, but then I
deleted it all.  You need to be able to look at that line an work out
what it does on your own.  My explaining it step by step will not help,
but if you write out what you think it does, I'll happily check it
over.

<snip>
-- 
Ben.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web