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


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

How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead?

Started byrivkaumiller@gmail.com
First post2014-03-30 19:04 -0700
Last post2014-03-31 08:55 -0700
Articles 20 on this page of 42 — 12 participants

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


Contents

  How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? rivkaumiller@gmail.com - 2014-03-30 19:04 -0700
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Richard Damon <Richard@Damon-Family.org> - 2014-03-30 22:31 -0400
      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? rivkaumiller@gmail.com - 2014-03-30 19:43 -0700
        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Richard Damon <Richard@Damon-Family.org> - 2014-03-30 23:09 -0400
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? rivkaumiller@gmail.com - 2014-03-30 19:35 -0700
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? rivkaumiller@gmail.com - 2014-03-30 19:47 -0700
      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-03-31 11:53 +0100
        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-03-31 17:50 +0000
          Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Kaz Kylheku <kaz@kylheku.com> - 2014-03-31 18:55 +0000
            Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-03-31 22:51 +0100
              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Kaz Kylheku <kaz@kylheku.com> - 2014-03-31 22:46 +0000
                Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-01 00:03 +0100
                Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-03-31 20:33 -0400
                  Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-01 09:35 +0100
                    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-04-01 07:35 -0700
                      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-01 17:19 +0100
                        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-04-01 10:14 -0700
                          Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-01 18:59 +0100
                            Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Öö Tiib <ootiib@hot.ee> - 2014-04-04 00:29 -0700
                              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-04 12:35 +0100
                              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Seungbeom Kim <musiphil@bawi.org> - 2014-04-08 11:48 -0700
                                Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Öö Tiib <ootiib@hot.ee> - 2014-04-08 15:52 -0700
                      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-02 18:38 +0000
                        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-04-02 11:48 -0700
                          Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-02 23:18 +0000
                            Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Kaz Kylheku <kaz@kylheku.com> - 2014-04-03 00:05 +0000
                            Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? James Kuyper <jameskuyper@verizon.net> - 2014-04-02 21:12 -0400
                            Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-04-02 19:16 -0700
                              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-03 03:16 +0000
                        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? James Kuyper <jameskuyper@verizon.net> - 2014-04-02 15:07 -0400
                    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-04-01 23:00 +0100
                      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Seungbeom Kim <musiphil@bawi.org> - 2014-04-08 11:56 -0700
              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2014-04-01 02:14 +0300
              Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-01 04:52 +0000
                Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? "BartC" <bc@freeuk.com> - 2014-04-01 09:56 +0100
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-03-30 22:49 -0400
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? James Kuyper <jameskuyper@verizon.net> - 2014-03-30 22:58 -0400
      Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? rivkaumiller@gmail.com - 2014-03-31 09:10 -0700
        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? James Kuyper <jameskuyper@verizon.net> - 2014-03-31 12:25 -0400
        Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-03-31 10:56 -0700
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? James Kuyper <jameskuyper@verizon.net> - 2014-03-30 23:09 -0400
    Re: How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead? Keith Thompson <kst-u@mib.org> - 2014-03-31 08:55 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#42681

FromSeungbeom Kim <musiphil@bawi.org>
Date2014-04-08 11:48 -0700
Message-ID<li1ga5$koc$1@usenet.stanford.edu>
In reply to#42562
On 2014-04-04 00:29, Öö Tiib wrote:
> On Tuesday, 1 April 2014 20:59:10 UTC+3, Bart  wrote:
>>
>> ... and that argument is generally used. And in fact I've had to resort to 
>> such a macro because of 100% of my for-loops do just iterate from A to B and 
>> the regular for-statement is too long-winded and error-prone.
> 
> You seem to assume [A,B] on close to all cases; someone else assumes [A,B)
> on close to all cases. Both assumptions make sense. 
> 
> Traditional 'for' cycle makes it explicit what it is; the macros hide it.
> So the macros are less error prone only for author of macro and that
> is exactly the state-of-art situation. ;)

Then let the macro be used like FOR(i, A, <=B) or FOR(i, A, <B).

Then why not support decrements or arbitrary step sizes as well?
FOR(i, A, >=0, --), FOR(i, A, <B, +=2), FOR(i, A, >0, >>=1), etc.

:-)

-- 
Seungbeom Kim

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


#42697

FromÖö Tiib <ootiib@hot.ee>
Date2014-04-08 15:52 -0700
Message-ID<62a7fd83-9b17-4523-a1f1-303ee84766bb@googlegroups.com>
In reply to#42681
On Tuesday, 8 April 2014 21:48:34 UTC+3, Seungbeom Kim  wrote:
> On 2014-04-04 00:29, Öö Tiib wrote:
> > On Tuesday, 1 April 2014 20:59:10 UTC+3, Bart  wrote:
> >>
> >> ... and that argument is generally used. And in fact I've had to resort to 
> >> such a macro because of 100% of my for-loops do just iterate from A to B and 
> >> the regular for-statement is too long-winded and error-prone.
> > 
> > You seem to assume [A,B] on close to all cases; someone else assumes [A,B)
> > on close to all cases. Both assumptions make sense. 
> > 
> > Traditional 'for' cycle makes it explicit what it is; the macros hide it.
> > So the macros are less error prone only for author of macro and that
> > is exactly the state-of-art situation. ;)
> 
> Then let the macro be used like FOR(i, A, <=B) or FOR(i, A, <B).
> 
> Then why not support decrements or arbitrary step sizes as well?
> FOR(i, A, >=0, --), FOR(i, A, <B, +=2), FOR(i, A, >0, >>=1), etc.
> 
> :-)

Not sure if that fits into "proper for statement" of Bart, but
it would indeed cover close to 100% variants I see in code ... 
like FOR(p, A, !=NULL, =p->next) ... FOR(i, i, <B, ++). 

Some with additional constraints like 

  for (i = a; weStillCare() && i < b; i++)

remain, but  FOR(i,a,<b,++) and 'if (!weStillCare()) break;' in start 
of body of loop work about same. 

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


#42477

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-02 18:38 +0000
Message-ID<lhhle8$113$1@speranza.aioe.org>
In reply to#42451
"BartC" <bc@freeuk.com> writes:

> (I can just imagine the hairy compilers the people on here 
> might write which will be parsing source input even as the 
> programmer is still adding lines at the end! Sometimes you 
> just have to state the kind of file model that you want to 
> support, and insist that the files conform to that model.)

I don't know that any Unix compilers will accept /dev/tty as
an input file. I did once with TOPS-10 and Fortran-10 on a
PDP-10 compile direct from terminal input. If you make any
mistakes, you have to start over, so it helps to have a small
program.

-- glen

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


#42479

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 11:48 -0700
Message-ID<lnlhvnftz1.fsf@nuthaus.mib.org>
In reply to#42477
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> "BartC" <bc@freeuk.com> writes:
>> (I can just imagine the hairy compilers the people on here 
>> might write which will be parsing source input even as the 
>> programmer is still adding lines at the end! Sometimes you 
>> just have to state the kind of file model that you want to 
>> support, and insist that the files conform to that model.)
>
> I don't know that any Unix compilers will accept /dev/tty as
> an input file. I did once with TOPS-10 and Fortran-10 on a
> PDP-10 compile direct from terminal input. If you make any
> mistakes, you have to start over, so it helps to have a small
> program.

I don't know of any that don't:

% gcc -x c -o hello /dev/tty
#include <stdio.h>
int main(void) { puts("hello"); }
% ./hello
hello

-- 
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]


#42498

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-02 23:18 +0000
Message-ID<lhi5sa$a68$1@speranza.aioe.org>
In reply to#42479
Keith Thompson <kst-u@mib.org> wrote:

(snip, I wrote)

>> I don't know that any Unix compilers will accept /dev/tty as
>> an input file. I did once with TOPS-10 and Fortran-10 on a
>> PDP-10 compile direct from terminal input. If you make any
>> mistakes, you have to start over, so it helps to have a small
>> program.
 
> I don't know of any that don't:

Last time I tried, the compiler required a .c extension.
Seems that gcc doesn't require that any more.

How about compilers other than gcc?
 
> % gcc -x c -o hello /dev/tty
> #include <stdio.h>
> int main(void) { puts("hello"); }
> % ./hello
> hello

-- glen

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


#42500

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-03 00:05 +0000
Message-ID<20140402170123.176@kylheku.com>
In reply to#42498
On 2014-04-02, glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
> Keith Thompson <kst-u@mib.org> wrote:
>
> (snip, I wrote)
>
>>> I don't know that any Unix compilers will accept /dev/tty as
>>> an input file. I did once with TOPS-10 and Fortran-10 on a
>>> PDP-10 compile direct from terminal input. If you make any
>>> mistakes, you have to start over, so it helps to have a small
>>> program.
>  
>> I don't know of any that don't:
>
> Last time I tried, the compiler required a .c extension.
> Seems that gcc doesn't require that any more.
>
> How about compilers other than gcc?

Compilers that need a filesystem object with a .c extension
can be fooled by a Unix fifo.

   mkfifo fake.c
   cc -c fake.c &  # blocks on open("fake.c", ...) syscall
   some_process > fake.c

now the compiler is possibly compiling pieces of code from the pipe before
some_process finishes writing it all.

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


#42501

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-04-02 21:12 -0400
Message-ID<lhicik$pvh$1@dont-email.me>
In reply to#42498
On 04/02/2014 07:18 PM, glen herrmannsfeldt wrote:
> Keith Thompson <kst-u@mib.org> wrote:
> 
> (snip, I wrote)
> 
>>> I don't know that any Unix compilers will accept /dev/tty as
>>> an input file. I did once with TOPS-10 and Fortran-10 on a
>>> PDP-10 compile direct from terminal input. If you make any
>>> mistakes, you have to start over, so it helps to have a small
>>> program.
>  
>> I don't know of any that don't:
> 
> Last time I tried, the compiler required a .c extension.
> Seems that gcc doesn't require that any more.

I'm not sure that it ever did; I am sure that it hasn't required it for
a long time. I'm also sure that most of the other compilers I've ever
used had options for accepting non-default file naming conventions.you
-- 
James Kuyper

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


#42503

FromKeith Thompson <kst-u@mib.org>
Date2014-04-02 19:16 -0700
Message-ID<lnr45fduon.fsf@nuthaus.mib.org>
In reply to#42498
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> wrote:
> (snip, I wrote)
>
>>> I don't know that any Unix compilers will accept /dev/tty as
>>> an input file. I did once with TOPS-10 and Fortran-10 on a
>>> PDP-10 compile direct from terminal input. If you make any
>>> mistakes, you have to start over, so it helps to have a small
>>> program.
>  
>> I don't know of any that don't:
>
> Last time I tried, the compiler required a .c extension.
> Seems that gcc doesn't require that any more.
>
> How about compilers other than gcc?
>  
>> % gcc -x c -o hello /dev/tty
>> #include <stdio.h>
>> int main(void) { puts("hello"); }
>> % ./hello
>> hello

It requires *some* way to know that the file contains C source (since
the "gcc" command is a driver capable of invoking compilers for several
different languages).  Usually that's done by giving it a file whose
name ends in ".c", but in this case, the "-x c" option serves the same
purpose.

-- 
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]


#42506

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-03 03:16 +0000
Message-ID<lhijqc$59g$1@speranza.aioe.org>
In reply to#42503
Keith Thompson <kst-u@mib.org> wrote:
> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>> Keith Thompson <kst-u@mib.org> wrote:
>> (snip, I wrote)

>>>> I don't know that any Unix compilers will accept /dev/tty as
>>>> an input file. I did once with TOPS-10 and Fortran-10 on a
>>>> PDP-10 compile direct from terminal input. If you make any
>>>> mistakes, you have to start over, so it helps to have a small
>>>> program.
  
>>> I don't know of any that don't:

>> Last time I tried, the compiler required a .c extension.
>> Seems that gcc doesn't require that any more.

>> How about compilers other than gcc?
  
(snip) 
> It requires *some* way to know that the file contains C source (since
> the "gcc" command is a driver capable of invoking compilers for several
> different languages).  Usually that's done by giving it a file whose
> name ends in ".c", but in this case, the "-x c" option serves the same
> purpose.

Before gcc compiled for different languages, it still allowed linking
in .o files, and sometimes assembling .s files.  I was writing C
back to SunOS 3.x and other computers before that. It could be
that I missed the option.

VMS programs in general, and not just compilers, mostly have
a preferred extension (if none is specified) or will accept
any extension you supply. (For example TYPE defaults to .LIS
if none is specified.) 

TOPS-10 is slightly different, but mostly has preferred extension,
but will accept any when supplied.

-- glen

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


#42482

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-04-02 15:07 -0400
Message-ID<533C5FF8.1050305@verizon.net>
In reply to#42477
On 04/02/2014 02:38 PM, glen herrmannsfeldt wrote:
...
> I don't know that any Unix compilers will accept /dev/tty as
> an input file.

~(49) gcc -xc /dev/tty -o from_terminal
#include <stdio.h>
int main(void) {
    printf("Hello World!\n");
    return 0;
}
~(50) from_terminal
Hello World!

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


#42457

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-04-01 23:00 +0100
Message-ID<0.1877974d52442e392a02.20140401230041BST.87y4zor9py.fsf@bsb.me.uk>
In reply to#42445
"BartC" <bc@freeuk.com> writes:
<snip>
 2014-03-31, BartC <bc@freeuk.com> wrote:
<snip>
>>>> I can
>>>> write an outline file-processing loop right now:
>>>>
>>>> while (!eof(f)) {
<snip>
> But for the million situations where you just have a small, static
> line-oriented text file which has a well-defined beginning and end,
> then my eof()/readline() loop works perfectly well.

It often works, but it's almost always wrong from the point of view of
expression the program's intent.  I can't remember the last time I cared
if I had hit the end of a file (or whatever).  What I care about is if
the read worked, or if the data was of the right sort, or if it meets
some other condition.  Writing

  while (read_and_check_data(...) == SUCCESS) {
       ...
  }

is almost always better than

  while (!one_possible_reason_for_failure(...)) {
       ...
  }

What the OP wants is

  while (fscanf(fp, "%d", &input) == 1) {
       /* do something with 'input' */
  }

or, if there are further restrictions on the numbers, something like
this:

  while (fscanf(fp, "%d", &input) == 1 && input >= 0) {
       /* do something with 'input' */
  }

and that's almost certainly better than any loop that checks for EOF
instead of input success.

<snip>
-- 
Ben.

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


#42682

FromSeungbeom Kim <musiphil@bawi.org>
Date2014-04-08 11:56 -0700
Message-ID<li1gov$l42$1@usenet.stanford.edu>
In reply to#42457
On 2014-04-01 15:00, Ben Bacarisse wrote:
> What I care about is if the read worked, or if the data was
> of the right sort, or if it meets some other condition.  Writing
> 
>   while (read_and_check_data(...) == SUCCESS) {
>        ...
>   }
> 
> is almost always better than
> 
>   while (!one_possible_reason_for_failure(...)) {
>        ...
>   }

This is analogous to

    if (mkdir(name) fails) {
        print "mkdir failed";
        return false;
    }
    return true;

being better than

    if (exists(name)) {
        print "name already exists";
        return false;
    }
    mkdir(name);    // assume success
    return true;

though for a somewhat different reason.

-- 
Seungbeom Kim

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


#42428

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2014-04-01 02:14 +0300
Message-ID<874n2enepw.fsf@bazspaz.fatphil.org>
In reply to#42420
"BartC" <bc@freeuk.com> writes:
> "Kaz Kylheku" <kaz@kylheku.com> wrote in message
> news:20140331112157.632@kylheku.com...
> > On 2014-03-31, glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
> >> BartC <bc@freeuk.com> wrote:
> 
> >>> End-of-file checking in C is a bit funny, because you only get an
> >>> eof status after attempting to read input.
> >>
> >> Seems to me that Pascal is funny, in that it tests EOF before reading
> >> the end of file.
> >
> > In the Pascal wrong, this design is acknowledged as being wrong
> > because it's
> > not repeated Wirth's successors to Pascal like Oberon and Modula 2.
> >
> > Modula 2 calls streams "channels".  A read operation produces a result
> > which is tested afterward. For instance, ReadChar tries to read a
> > character
> > and store it to a CHAR location via a VAR parameter. Afer ReacChar,
> > you have to call ReadResult on the channel. Only if that result is
> > allRight
> > was the character read successfully.
> 
> Wrong or not, the Pascal design is far simpler to use. For example, I
> can write an outline file-processing loop right now:
> 
> while (!eof(f)) {
>     .....
> }
> 
> before I even have any idea of what's to go in the loop!

If you don't know what's going on in the loop, perhaps you
shouldn't be writing it at all?

> Or I can
> change the kind of reads I want to do, while the loop logic stays the
> same.

False. You need to change the return value checks to match
the kinds of reads that you're doing. And if you need to 
to that, when why not just have the check in the while's
conditional clause?

> It also means the main read function can actually be in the body
> of the loop, instead of always being part of the loop condition; not
> quite as readable.

Only if you're not familiar with, or simply intrinsically biased
against, that convention. For me, as long as the read functions 
are sane (and in case they're not there's always the possibility
of creating sane wrappers) it's a perfectly readable convention. 

Phil
-- 
Religion is too important a matter to its devotees to be a subject of 
ridicule. If they indulge in absurdities, they are to be pitied rather
than ridiculed. -- Immanuel Kant (1724-1804), lecture at Konigsberg, 1775

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


#42439

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2014-04-01 04:52 +0000
Message-ID<lhdgmr$s5k$1@speranza.aioe.org>
In reply to#42420
BartC <bc@freeuk.com> wrote:
> "Kaz Kylheku" <kaz@kylheku.com> wrote in message 
> news:20140331112157.632@kylheku.com...

(snip regarding EOF testing)
>> In the Pascal wrong, this design is acknowledged as being wrong 
>> because it's not repeated Wirth's successors to Pascal like 
>> Oberon and Modula 2.

(snip)

> Wrong or not, the Pascal design is far simpler to use. For 
> example, I can write an outline file-processing loop right now:
 
> while (!eof(f)) {
>    .....
> }
 
> before I even have any idea of what's to go in the loop! 
> Or I can change the kind of reads I want to do, while the loop 
> logic stays the same. It also means the main read function can 
> actually be in the body of the loop, instead of always being 
> part of the loop condition; not quite as readable.

But you don't know that it is EOF until you know what you want
to read.

If you consider Java Scanner, which is commonly used for stream
input, you tell it what you want to read, and it tells you if you
can read that.

Scanner s=new Scanner(System.in);

while(s.hasNextDouble()) {
   System.out.println(s.nextDouble());
   }

The loop will exit at EOF, or earlier than EOF if the rest of the
stream doesn't look like a double.   The file might have some blank
space left, and so not be at EOF, but no double.

s.hasNextChar() could still return true, though s.hasNextInt() 
would return false.

The other way to do it in Java is to catch the exception at end of
file and/or I/O error.

-- glen

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


#42446

From"BartC" <bc@freeuk.com>
Date2014-04-01 09:56 +0100
Message-ID<Pcv_u.108148$XE4.69526@fx26.am4>
In reply to#42439
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message 
news:lhdgmr$s5k$1@speranza.aioe.org...
> BartC <bc@freeuk.com> wrote:

>> Wrong or not, the Pascal design is far simpler to use. For
>> example, I can write an outline file-processing loop right now:
>
>> while (!eof(f)) {
>>    .....
>> }
>
>> before I even have any idea of what's to go in the loop!
>> Or I can change the kind of reads I want to do, while the loop
>> logic stays the same. It also means the main read function can
>> actually be in the body of the loop, instead of always being
>> part of the loop condition; not quite as readable.
>
> But you don't know that it is EOF until you know what you want
> to read.

> If you consider Java Scanner, which is commonly used for stream
> input, you tell it what you want to read, and it tells you if you
> can read that.

Well, I don't use stream input for files. EOF is perfectly well defined for 
many kinds of input: if the current position within the file is at the end, 
then ... you're at the end of the file!

If you're talking about 'files' that don't have a proper beginning or end, 
maybe a stream of characters coming over a wire, then fine, you take a 
different approach. But then, a lot of the stuff you might want to do will 
not be meaningful (how do you report an error on line 217 for example, if 
line 217 has come and gone since then?)

And if you have files which can change size and contents even as you read 
them, then you've got bigger problems than how to detect the end of them.

-- 
Bartc 

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


#42382

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-03-30 22:49 -0400
Message-ID<lhal43$n7r$1@dont-email.me>
In reply to#42373
On 3/30/2014 10:04 PM, rivkaumiller@gmail.com wrote:
> How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead?
>
> For example, compact while loops are written like this in k&r
>
> while ((c=getchar())!=NULL){
>
>    // do certain actions
>
> }
>
> and I want to convert a stanza like
>
> fscanf ( FpSource, "%d" , &input );
> while (input != EOF){
>
>    // do certain actions
>
>    fscanf ( FpSource, "%d" , &input );
> }
>
> into the above form with getchar() so that there is a single instance of fscanf.
>
> More than one alternative would be appreciated.

     Alternative #1,pretty much what you asked for:

	while ( fscanf(FpSource, "%d", &input) , input != EOF ) {

The funny-looking thing inside the while() is an expression using
the comma operator -- yes, the comma can be an operator in C --
which evaluates its left-hand side (the fscanf() call), throws
the result away, then evaluates the right-hand side (input != EOF)
and yields the right-hand side's value as the value of the whole
expression.

     I'd recommend against using this, though: There are too many
things that can go wrong.  For starters, C promises that EOF is a
negative int, but doesn't specify any particular value.  It is
very often -1, but could be something else (a case could be made
for -129 on some systems), so you don't really *know* what number
you should enter to stop the loop.  Even if you do know the system's
EOF value (-1, say), what happens if you actually want to enter -1
as a legitimate datum?  You're out of luck.

     A worse problem occurs if fscanf() encounters "12.0" in the
input stream, or anything else that isn't strictly an int value.
On the first attempt it will digest "12", see that "." isn't a
digit and leave it alone, and store 12 in `input'.  On the next
attempt it will see the "." again, realize that it can't make
any progress, and leave things unchanged: `input' will still be
12 from the first time.  And you'll keep on getting 12 as the
value of `input' on the third, fourth, fifth, ... time until you
finally get tired and pull the plug on your program.  Similar
trouble occurs if the input is "$42" or "(17)" or a myriad of
other non-numeric stuff.

     Which leads us to Alternative #2, not what you asked for but
perhaps closer to what you should have asked for:

	while (fscanf(FpSource, "%d", &input) == 1) {

In this alternative you're not making the continue/stop decision
based on the value of the number from the input, but on whether
fscanf() was able to find a number at all.  fscanf() returns the
number of items it successfully read and stored; you're asking
for one item, so fscanf() returns 1 if and only if it was actually
able to make integer sense of its input.  In the "12.0" example
above, the first call would convert "12" to 12, store it in `input',
and return 1.  The second call would stall on the ".", leave `input'
unchanged, and return 0 -- and your program would then know that
you'd either reached the end of the input stream or encountered
something undigestible in it.

     You might be interested in telling those two cases apart,
which leads to Alternative #3:

	int status;
	...
	while ((status = fscanf(FpSource, "%d", &input)) == 1) {
	    ...
	}
	if (status == EOF) {
	    ... read all the way to the end ...
	} else {
	    ... found garbage somewhere in mid-stream ...
	}

     I might use #3 in a quick one-off program or if I had good
reason to believe the input was well-structured (e.g., the input
was the unedited output of some other program known to be well-
behaved).  For input from a less well-controlled source -- in
particular, for interactive input -- even #3 isn't robust enough
for real-world use.  I'll refer you to Question 12.20 and its
various links and footnotes on the comp.lang.c Frequently Asked
Questions (FAQ) page at <http://www.c-faq.com/> for an exposition
of some of the issues and some hints about coping with them.


-- 
Eric Sosman
esosman@comcast-dot-net.invalid

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


#42383

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-03-30 22:58 -0400
Message-ID<lhaljr$pdn$1@dont-email.me>
In reply to#42373
On 03/30/2014 10:04 PM, rivkaumiller@gmail.com wrote:
> How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead?
> 
> For example, compact while loops are written like this in k&r
> 
> while ((c=getchar())!=NULL){
> 
>   // do certain actions
> 
> }
> 
> and I want to convert a stanza like
> 
> fscanf ( FpSource, "%d" , &input );
> while (input != EOF){
> 
>   // do certain actions
> 
>   fscanf ( FpSource, "%d" , &input );
> }
> 
> into the above form with getchar() so that there is a single instance of fscanf.
> 
> More than one alternative would be appreciated.

The following code has the exact same behavior as your loop, except that
it contains only one call to fscanf():

while(fscanf ( FpSource, "%d" , &input ), input != EOF)
{
   // do certain actions
}

However, that isn't a very good idea.
"The fscanf function returns the value of the macro EOF if an input
failure occurs before the first conversion (if any) has completed.
Otherwise, the function returns the number of input items assigned,
which can be fewer than provided for, or even zero, in the event of an
early matching failure." (7.21.6.2p16)

Your code pays no attention to the value returned by fscanf(), which
means it does nothing to deal with the possibility that anything might
go wrong when you call it. This could lead, among other possibilities,
to the value of 'input' being unequal to EOF, and never changing,
because fscanf() has reached the end of the file or has an input
failure, so you've written an infinite loop.

What your code does is check input != EOF, which will be false only
under two circumstances:
a) input has a value of EOF at the start of the loop, and the first call
to fscanf() fails, leaving that value unchanged.
b) fscanf() completes successfully, loading input with a value equal to
EOF that was read from FpSource.

In principle, this could be a legitimate way of marking the end of your
input data. However, it suggests to me the possibility that you're
confused about how fscanf() works, and thought that input == EOF would
be the way to determine whether or not the call to fscanf() succeeded.

int status;
while((status = fscanf(FpSource, "%d", &input)) != EOF)
{
   if(status != 1)
   {
      // Handle early matching failure
   }
   else
   {
      // do certain actions
   }
}
if(ferror(FpSource))
{
    // Handle I/O error
}
else
{
    // Handle end of file
}

How you handle each of those situations is up to you. End of File, in
particular, is a perfectly normal thing, except when it occurs at a time
when it shouldn't be occurring, such as after the tenth number in a file
that was supposed to contain 100 numbers.

If you choose to simplify the code by removing all of the handling
sections, you can drop the corresponding else blocks, and even the
second if(). However, do NOT remove the if(status != 1) test. If status
is not equal to 1, then the value of 'input' is indeterminate. That
means it can be either an unspecified integer, or a trap
representations. Any attempt to use a trap representation has undefined
behavior, but very few implementations support 'int' types with trap
representations. Much more important is the fact that the value of
'input' is unspecified. That doesn't mean that it's random - it could be
highly predictable if you know enough about that particular
implementation of the C standard library. However, it does mean that
there's no guarantees about which value it has. There's nothing useful
your program can portably do with that value, so it should not "do
certain actions" using that value.
-- 
James Kuyper

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


#42404

Fromrivkaumiller@gmail.com
Date2014-03-31 09:10 -0700
Message-ID<fa235e5a-0578-4faa-9820-da08ac73674c@googlegroups.com>
In reply to#42383
On Sunday, March 30, 2014 7:58:03 PM UTC-7, James Kuyper wrote:
> On 03/30/2014 10:04 PM, riv......@gmail.com wrote:
> 
> > How to modify ((c=getchar())!=NULL) to use fscanf or scanf instead?
> 
> > 
> 
> > For example, compact while loops are written like this in k&r
> 
> > 
> 
> > while ((c=getchar())!=NULL){
> 
> > 
> 
> >   // do certain actions
> 
> > 
> 
> > }
> 
> > 
> 
> > and I want to convert a stanza like
> 
> > 
> 
> > fscanf ( FpSource, "%d" , &input );
> 
> > while (input != EOF){
> 
> > 
> 
> >   // do certain actions
> 
> > 
> 
> >   fscanf ( FpSource, "%d" , &input );
> 
> > }
> 
> > 
> 
> > into the above form with getchar() so that there is a single instance of fscanf.
> 
> > 
> 
> > More than one alternative would be appreciated.
> 
> 
> 
> The following code has the exact same behavior as your loop, except that
> 
> it contains only one call to fscanf():
> 
> 
> 
> while(fscanf ( FpSource, "%d" , &input ), input != EOF)
> 
> {
> 
>    // do certain actions
> 
> }
> 
> 
> 
> However, that isn't a very good idea.
> 
> "The fscanf function returns the value of the macro EOF if an input
> 
> failure occurs before the first conversion (if any) has completed.
> 
> Otherwise, the function returns the number of input items assigned,
> 
> which can be fewer than provided for, or even zero, in the event of an
> 
> early matching failure." (7.21.6.2p16)
> 
> 
> 
> Your code pays no attention to the value returned by fscanf(), which
> 
> means it does nothing to deal with the possibility that anything might
> 
> go wrong when you call it. This could lead, among other possibilities,
> 
> to the value of 'input' being unequal to EOF, and never changing,
> 
> because fscanf() has reached the end of the file or has an input
> 
> failure, so you've written an infinite loop.
> 
> 
> 
> What your code does is check input != EOF, which will be false only
> 
> under two circumstances:
> 
> a) input has a value of EOF at the start of the loop, and the first call
> 
> to fscanf() fails, leaving that value unchanged.
> 
> b) fscanf() completes successfully, loading input with a value equal to
> 
> EOF that was read from FpSource.
> 
> 
> 
> In principle, this could be a legitimate way of marking the end of your
> 
> input data. However, it suggests to me the possibility that you're
> 
> confused about how fscanf() works, and thought that input == EOF would
> 
> be the way to determine whether or not the call to fscanf() succeeded.
> 
> 
> 
> int status;
> 
> while((status = fscanf(FpSource, "%d", &input)) != EOF)
> 
> {
> 
>    if(status != 1)
> 
>    {
> 
>       // Handle early matching failure
> 
>    }
> 
>    else
> 
>    {
> 
>       // do certain actions
> 
>    }
> 
> }
> 
> if(ferror(FpSource))
> 
> {
> 
>     // Handle I/O error
> 
> }
> 
> else
> 
> {
> 
>     // Handle end of file
> 
> }
> 

Thanks to everyone who replied.

"status" is a good self-commenting alias for the return value of fscanf().

I finally found this worked well

while (fscanf ( FpSource, "%d" , &input ) != EOF){

  // do certain actions with "input"

}

as all it cares about is reaching the end of the input file.

Concluded.


> 
> How you handle each of those situations is up to you. End of File, in
> 
> particular, is a perfectly normal thing, except when it occurs at a time
> 
> when it shouldn't be occurring, such as after the tenth number in a file
> 
> that was supposed to contain 100 numbers.
> 
> 
> 
> If you choose to simplify the code by removing all of the handling
> 
> sections, you can drop the corresponding else blocks, and even the
> 
> second if(). However, do NOT remove the if(status != 1) test. If status
> 
> is not equal to 1, then the value of 'input' is indeterminate. That
> 
> means it can be either an unspecified integer, or a trap
> 
> representations. Any attempt to use a trap representation has undefined
> 
> behavior, but very few implementations support 'int' types with trap
> 
> representations. Much more important is the fact that the value of
> 
> 'input' is unspecified. That doesn't mean that it's random - it could be
> 
> highly predictable if you know enough about that particular
> 
> implementation of the C standard library. However, it does mean that
> 
> there's no guarantees about which value it has. There's nothing useful
> 
> your program can portably do with that value, so it should not "do
> 
> certain actions" using that value.
> 
> -- 
> 
> James Kuyper

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


#42406

FromJames Kuyper <jameskuyper@verizon.net>
Date2014-03-31 12:25 -0400
Message-ID<533996EF.2090609@verizon.net>
In reply to#42404
On 03/31/2014 12:10 PM, rivkaumiller@gmail.com wrote:
> On Sunday, March 30, 2014 7:58:03 PM UTC-7, James Kuyper wrote:
...
>> int status;
>> while((status = fscanf(FpSource, "%d", &input)) != EOF)
>> {
>>    if(status != 1)
>>    {
>>       // Handle early matching failure
>>    }
...
> "status" is a good self-commenting alias for the return value of fscanf().
> 
> I finally found this worked well
> 
> while (fscanf ( FpSource, "%d" , &input ) != EOF){
>   // do certain actions with "input"
> }
> 
> as all it cares about is reaching the end of the input file.

And it therefore does not address this issue:

>> If you choose to simplify the code by removing all of the handling
>> sections, you can drop the corresponding else blocks, and even the
>> second if(). However, do NOT remove the if(status != 1) test. If status
>> is not equal to 1, then the value of 'input' is indeterminate. That
>> means it can be either an unspecified integer, or a trap
>> representations. Any attempt to use a trap representation has undefined
>> behavior, but very few implementations support 'int' types with trap
>> representations. Much more important is the fact that the value of
>> 'input' is unspecified. That doesn't mean that it's random - it could be
>> highly predictable if you know enough about that particular
>> implementation of the C standard library. However, it does mean that
>> there's no guarantees about which value it has. There's nothing useful
>> your program can portably do with that value, so it should not "do
>> certain actions" using that value.

Are you certain that your input stream won't have any early matching
errors? Such certainty is often a matter of self-delusion.

Or do you simply not care about the possibility that your program might
end up processing meaningless values that have nothing to do with the
contents of your input file? If that's not a problem, you can simplify
your program a great deal by not even bothering to read that file.

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


#42410

FromKeith Thompson <kst-u@mib.org>
Date2014-03-31 10:56 -0700
Message-ID<lnsipygslq.fsf@nuthaus.mib.org>
In reply to#42404
rivkaumiller@gmail.com writes:
[...]
> I finally found this worked well
>
> while (fscanf ( FpSource, "%d" , &input ) != EOF){
>>   // do certain actions with "input"
>> }
>
> as all it cares about is reaching the end of the input file.
[...]

Ok, let's try that:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    long count = 0;
    FILE *FpSource = fopen("/etc/motd", "r");
    int input;

    if (FpSource == NULL) {
        fprintf(stderr, "Failed to open file\n");
        exit(EXIT_FAILURE);
    }

    while (fscanf ( FpSource, "%d" , &input ) != EOF) {
        count ++;
        if (count >= 1000000) {
            fprintf(stderr, "You didn't really want an infinite loop, did you?\n");
            exit(EXIT_FAILURE);
        }
    }
    fclose(FpSource);
}

The output on my system was "You didn't really want an infinite loop,
did you?".

The first line of /etc/motd on my system starts with the word "Welcome",
which is not an optionally signed decimal integer.  When fscanf() with a
"%d" format sees that, it returns 0 (to denote the number of items it
was able to read) and leaves the entire line waiting to be read by the
next input call -- which is the fscanf() call in the next iteration of
the same loop.

fprintf() returns the number of items you asked it to read (1 in this
case) if it was successful, some value less than that if it was
unsuccessful, or EOF if an input failure occurs before the first value
has completed.  You have to allow for all those possibilities.

-- 
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]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

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


csiph-web