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


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

While or if: function to get next operator or operand

Started byAlla _ <modelling.data@gmail.com>
First post2015-11-20 08:06 -0800
Last post2015-11-20 20:43 -0800
Articles 20 on this page of 68 — 18 participants

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


Contents

  While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 08:06 -0800
    Re: While or if: function to get next operator or operand Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-20 08:17 -0800
      Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-20 16:44 +0000
    Re: While or if: function to get next operator or operand Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-20 11:23 -0500
      Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 08:39 -0800
        Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-20 16:47 +0000
        Re: While or if: function to get next operator or operand Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-20 11:54 -0500
          Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 09:13 -0800
          Re: While or if: function to get next operator or operand David Thompson <dave.thompson2@verizon.net> - 2015-12-06 08:04 -0500
        Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-20 12:02 -0500
    Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-20 16:41 +0000
      Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 09:11 -0800
        Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-20 17:39 +0000
          Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 10:42 -0800
          Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-21 14:58 -0500
            Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-23 12:21 +0000
          Re: While or if: function to get next operator or operand Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 21:29 +0000
            Re: While or if: function to get next operator or operand BartC <bc@freeuk.com> - 2015-11-21 22:31 +0000
              Re: While or if: function to get next operator or operand BartC <bc@freeuk.com> - 2015-11-22 10:57 +0000
                Re: While or if: function to get next operator or operand Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-22 13:45 +0000
            Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-22 01:31 -0500
            Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 04:33 -0800
              Re: While or if: function to get next operator or operand Philip Lantz <prl@canterey.us> - 2015-11-23 23:44 -0800
          Re: While or if: function to get next operator or operand Rosario19 <Ros@invalid.invalid> - 2015-11-22 09:39 +0100
            Re: While or if: function to get next operator or operand Rosario19 <Ros@invalid.invalid> - 2015-11-22 09:49 +0100
              Re: While or if: function to get next operator or operand asetofsymbols@gmail.com - 2015-11-22 02:27 -0800
                Re: While or if: function to get next operator or operand asetofsymbols@gmail.com - 2015-11-22 02:32 -0800
          Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-22 10:02 -0500
            Re: While or if: function to get next operator or operand Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-23 17:23 +0000
              Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-23 12:31 -0500
                Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-23 13:02 -0500
          Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-22 07:06 -0800
            Re: While or if: function to get next operator or operand Barry Schwarz <schwarzb@dqel.com> - 2015-11-22 11:43 -0800
              Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-24 02:03 -0800
              Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-24 02:11 -0800
                Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-24 07:09 -0500
            Re: While or if: function to get next operator or operand Richard Heathfield <rjh@cpax.org.uk> - 2015-11-23 12:26 +0000
              Re: While or if: function to get next operator or operand raltbos@xs4all.nl (Richard Bos) - 2015-11-23 13:26 +0000
          Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-22 07:17 -0800
    Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-20 12:15 -0500
      Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 10:44 -0800
      Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-20 12:31 -0800
        Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-20 15:38 -0500
          Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-20 16:14 -0500
            Re: While or if: function to get next operator or operand Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2015-11-20 16:55 -0500
              Re: While or if: function to get next operator or operand Geoff <geoff@invalid.invalid> - 2015-11-20 15:04 -0800
          Re: While or if: function to get next operator or operand Barry Schwarz <schwarzb@dqel.com> - 2015-11-20 20:59 -0800
          Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 23:50 -0800
            Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-21 00:18 -0800
          Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-22 14:10 -0800
        Re: While or if: function to get next operator or operand Philip Lantz <prl@canterey.us> - 2015-11-22 19:00 -0800
          Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-23 06:57 -0500
            Re: While or if: function to get next operator or operand Philip Lantz <prl@canterey.us> - 2015-11-23 23:49 -0800
              Re: While or if: function to get next operator or operand James Kuyper <jameskuyper@verizon.net> - 2015-11-24 07:13 -0500
          Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-23 07:55 -0800
            Re: While or if: function to get next operator or operand Philip Lantz <prl@canterey.us> - 2015-11-23 23:36 -0800
              Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-27 13:32 -0800
      Re: While or if: function to get next operator or operand Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-20 16:13 -0500
        Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-22 13:54 -0800
    Re: While or if: function to get next operator or operand Geoff <geoff@invalid.invalid> - 2015-11-20 12:19 -0800
    Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-20 15:32 -0800
      Re: While or if: function to get next operator or operand Chad <cdalten@gmail.com> - 2015-11-20 18:38 -0800
        Re: While or if: function to get next operator or operand Keith Thompson <kst-u@mib.org> - 2015-11-20 19:45 -0800
          Re: While or if: function to get next operator or operand Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-20 20:12 -0800
        Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 20:45 -0800
          Re: While or if: function to get next operator or operand Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-20 21:04 -0800
        Re: While or if: function to get next operator or operand Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-22 13:57 -0800
      Re: While or if: function to get next operator or operand Alla _ <modelling.data@gmail.com> - 2015-11-20 20:43 -0800

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


#76660

FromAlla _ <modelling.data@gmail.com>
Date2015-11-20 10:44 -0800
Message-ID<de686c37-037e-4f0a-b51f-d10afd61b168@googlegroups.com>
In reply to#76653
<snip>
Thank you for your answer. I see my mistake. 

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


#76665

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-11-20 12:31 -0800
Message-ID<kfnsi409zwa.fsf@x-alumni2.alumni.caltech.edu>
In reply to#76653
James Kuyper <jameskuyper@verizon.net> writes:

> On 11/20/2015 11:06 AM, Alla _ wrote:
>> Hello!
>>
>> Please, take a look at the function below.  It is from K&R.
>>
>> I dare to wonder why they use a while loop if the condition
>> considers only one item in the list. ...
>
> It does not.  The loop keeps executing until getch() returns
> something other than ' ' or '\t'.
>
>> ... Why not to use if statement?
>
> Because that would execute the getch() only once.
>
>> What is the purpose and the logic behind the while loop in this
>> case?
>>
>> I have accidentally found confirmation of my
>> concern on stackoverflow:
>>
>> QUOTE:
>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
>>
>> @ammoQ Indeed.  And then people still recommend K&R, I have
>> absolutely no idea why.  Look at this horrible code, it is not
>> written by the OP, it is written by K&R!  Had any rookie
>> programmer written code like this today, he would have been
>> immediately fired. - Lundin
>>
>> UNQUOTE
>>
>> Function: 
>>
>> /* getop:  get next character or numeric operand */
>> int getop(char s[])
>> {
>>     int i, c;
>> /* the below while loop */
>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>         ;
>
> I disagree with ammoQ.  Once you've learned enough about C, such
> code should be quite clear.  [...]

For people who think this code snippet is clear - did you spot
the subtle bug?

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


#76666

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2015-11-20 15:38 -0500
Message-ID<lxL3y.112896$eE.77678@fx07.iad>
In reply to#76665
On Friday November 20 2015 15:31, in comp.lang.c, "Tim Rentsch"
<txr@alumni.caltech.edu> wrote:

> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 11/20/2015 11:06 AM, Alla _ wrote:
>>> Hello!
>>>
>>> Please, take a look at the function below.  It is from K&R.
>>>
>>> I dare to wonder why they use a while loop if the condition
>>> considers only one item in the list. ...
>>
>> It does not.  The loop keeps executing until getch() returns
>> something other than ' ' or '\t'.
>>
>>> ... Why not to use if statement?
>>
>> Because that would execute the getch() only once.
>>
>>> What is the purpose and the logic behind the while loop in this
>>> case?
>>>
>>> I have accidentally found confirmation of my
>>> concern on stackoverflow:
>>>
>>> QUOTE:
>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna
>>> weep. - ammoQ
>>>
>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>> absolutely no idea why.  Look at this horrible code, it is not
>>> written by the OP, it is written by K&R!  Had any rookie
>>> programmer written code like this today, he would have been
>>> immediately fired. - Lundin
>>>
>>> UNQUOTE
>>>
>>> Function:
>>>
>>> /* getop:  get next character or numeric operand */
>>> int getop(char s[])
>>> {
>>>     int i, c;
>>> /* the below while loop */
>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>         ;
>>
>> I disagree with ammoQ.  Once you've learned enough about C, such
>> code should be quite clear.  [...]
> 
> For people who think this code snippet is clear - did you spot
> the subtle bug?

Perhaps not the subtle bug you allude to, but...

What is getch()?

IIRC, getch() is not part of the C standard library. 

-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

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


#76676

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-11-20 16:14 -0500
Message-ID<564F8D3D.5020404@verizon.net>
In reply to#76666
On 11/20/2015 03:38 PM, Lew Pitcher wrote:
> On Friday November 20 2015 15:31, in comp.lang.c, "Tim Rentsch"
> <txr@alumni.caltech.edu> wrote:
> 
>> James Kuyper <jameskuyper@verizon.net> writes:
>>
>>> On 11/20/2015 11:06 AM, Alla _ wrote:
>>>> Hello!
>>>>
>>>> Please, take a look at the function below.  It is from K&R.
>>>>
>>>> I dare to wonder why they use a while loop if the condition
>>>> considers only one item in the list. ...
>>>
>>> It does not.  The loop keeps executing until getch() returns
>>> something other than ' ' or '\t'.
>>>
>>>> ... Why not to use if statement?
>>>
>>> Because that would execute the getch() only once.
>>>
>>>> What is the purpose and the logic behind the while loop in this
>>>> case?
>>>>
>>>> I have accidentally found confirmation of my
>>>> concern on stackoverflow:
>>>>
>>>> QUOTE:
>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna
>>>> weep. - ammoQ
>>>>
>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>> written by the OP, it is written by K&R!  Had any rookie
>>>> programmer written code like this today, he would have been
>>>> immediately fired. - Lundin
>>>>
>>>> UNQUOTE
>>>>
>>>> Function:
>>>>
>>>> /* getop:  get next character or numeric operand */
>>>> int getop(char s[])
>>>> {
>>>>     int i, c;
>>>> /* the below while loop */
>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>         ;
>>>
>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>> code should be quite clear.  [...]
>>
>> For people who think this code snippet is clear - did you spot
>> the subtle bug?

Well, for one thing, the code should check whether c==EOF after exiting
from this loop, and take action accordingly.

> Perhaps not the subtle bug you allude to, but...
> 
> What is getch()?
> 
> IIRC, getch() is not part of the C standard library.

On many systems it's a function that works similarly to getchar(), but
takes it's input directly from the console. I haven't programmed for any
such system in two decades, but I am familiar with the fact that getch()
exists. I'd like to claim that this is the reason I didn't comment on
it, but the truth of the matter is that failed to notice that it wasn't
a call to getchar(). That's not a particularly subtle error, and it's
not a consequence of the complexity of this code, so it might not be
what he's referring to.

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


#76685

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2015-11-20 16:55 -0500
Message-ID<NFM3y.76083$og6.46194@fx06.iad>
In reply to#76676
On Friday November 20 2015 16:14, in comp.lang.c, "James Kuyper"
<jameskuyper@verizon.net> wrote:

> On 11/20/2015 03:38 PM, Lew Pitcher wrote:
>> On Friday November 20 2015 15:31, in comp.lang.c, "Tim Rentsch"
>> <txr@alumni.caltech.edu> wrote:
>> 
>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>
>>>> On 11/20/2015 11:06 AM, Alla _ wrote:
>>>>> Hello!
>>>>>
>>>>> Please, take a look at the function below.  It is from K&R.
>>>>>
>>>>> I dare to wonder why they use a while loop if the condition
>>>>> considers only one item in the list. ...
>>>>
>>>> It does not.  The loop keeps executing until getch() returns
>>>> something other than ' ' or '\t'.
>>>>
>>>>> ... Why not to use if statement?
>>>>
>>>> Because that would execute the getch() only once.
>>>>
>>>>> What is the purpose and the logic behind the while loop in this
>>>>> case?
>>>>>
>>>>> I have accidentally found confirmation of my
>>>>> concern on stackoverflow:
>>>>>
>>>>> QUOTE:
>>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me
>>>>> wanna weep. - ammoQ
>>>>>
>>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>>> written by the OP, it is written by K&R!  Had any rookie
>>>>> programmer written code like this today, he would have been
>>>>> immediately fired. - Lundin
>>>>>
>>>>> UNQUOTE
>>>>>
>>>>> Function:
>>>>>
>>>>> /* getop:  get next character or numeric operand */
>>>>> int getop(char s[])
>>>>> {
>>>>>     int i, c;
>>>>> /* the below while loop */
>>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>>         ;
>>>>
>>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>>> code should be quite clear.  [...]
>>>
>>> For people who think this code snippet is clear - did you spot
>>> the subtle bug?
> 
> Well, for one thing, the code should check whether c==EOF after exiting
> from this loop, and take action accordingly.

Perhaps so. Perhaps such a test exists in the code that the OP didn't post.

>> Perhaps not the subtle bug you allude to, but...
>> 
>> What is getch()?
>> 
>> IIRC, getch() is not part of the C standard library.
> 
> On many systems it's a function that works similarly to getchar(), but
> takes it's input directly from the console.
[snip]

I know of three getch() functions:
1) The Unix Curses function that reads a character from a window, returning
   either ERR on failure or an integer value representing the character or
   KEY_ function selected by the user.
2) The Microsoft Windows function that reads a character directly from the
   keyboard, without echoing it's glyph to the screen, and
3) the getch() function who's source code is supplied in K&R, that implements
   an I/O buffer front to getchar().
I'm sure that there are others.

But, without any context from the OP (such as the inclusion of <curses.h> or
<conio.h>, or the source for getch(), as per K&R), we have no clue as to the
behaviour or return value of the getch() referenced in the OP's code.

-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

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


#76690

FromGeoff <geoff@invalid.invalid>
Date2015-11-20 15:04 -0800
Message-ID<n09v4bhipvgko7rpnq0ar7ruj1gqtm4np2@4ax.com>
In reply to#76685
On Fri, 20 Nov 2015 16:55:56 -0500, Lew Pitcher
<lew.pitcher@digitalfreehold.ca> wrote:

>But, without any context from the OP (such as the inclusion of <curses.h> or
><conio.h>, or the source for getch(), as per K&R), we have no clue as to the
>behaviour or return value of the getch() referenced in the OP's code.

The incorrectly quoted code is from Page 78 of K&R2.
I post the corrected version here:


#include <ctype.h>

int getch(void);
void ungetch(int);

/* getop: get next character or numeric operand */
int getop(char s[])
{
    int i, c;

    while ((s[0] = c = getch()) == ' ' || c == '\t')
        ;
    s[1] = '\0';

    if (!isdigit(c) && c != '.')
        return c;     /* not a number */

    i = 0;
    if (isdigit(c))   /* collect integer part */
        while (isdigit(s[++i] = c = getch()))
            ;

    if (c == '.')     /* collect fraction part */
        while (isdigit(s[++i] = c = getch()))
            ;
    s[i] = '\0';

    if (c != EOF)
        ungetch(c);

    return NUMBER;
}

The getch and ungetch functions are defined on page 79.

#define BUFSIZE 100

char buf[BUFSIZE];   /* buffer for ungetch */
int bufp = 0;        /* next free position in buf */

int getch(void)  /* get a (possibly pushed back) character */
{
    return (bufp > 0) ? bufp[--bufp] : getchar();
}

void ungetch(int c) /* push character back on input */
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

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


#76726

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-11-20 20:59 -0800
Message-ID<jeuv4bhpd9l4jm69ksfoj4qdbm78v204rh@4ax.com>
In reply to#76666
On Fri, 20 Nov 2015 15:38:41 -0500, Lew Pitcher
<lew.pitcher@digitalfreehold.ca> wrote:

<snip>

>What is getch()?
>
>IIRC, getch() is not part of the C standard library. 

getch and ungetch are functions that K&R defines as part of the
program under discussion.  They appear on the next page of the text.

-- 
Remove del for email

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


#76737

FromAlla _ <modelling.data@gmail.com>
Date2015-11-20 23:50 -0800
Message-ID<3b4be5fe-f895-4246-9700-dee705984f33@googlegroups.com>
In reply to#76666
> What is getch()?
> 
> IIRC, getch() is not part of the C standard library. 
>
Here is the whole program, getch and ungetch are below main function:

// Program to apply reverse Polish notation
#include <stdio.h>
#include <stdlib.h> /* for atof() */

#define MAXOP  100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */

int getop(char []);
void push(double);
double pop(void);

int main(void)
{
    int type;
    double op2;
    char s[MAXOP];
    
    while ((type = getop(s)) != EOF)
    {
        switch (type)
        {
            case NUMBER:
                push(atof(s));
                break;
            case '+':
                push(pop() + pop());
                break;
            case '*':
                push(pop() * pope());
                break;
            case '-' :
                op2 = pop();
                push (pop () - op2); /* subtract from the value that is the 
                                     latest in the stack => first comes op2, then
                                      pop() value => pop() is the latest */
                break;
            case '/':
                op2 = pop();
                if (op2 != 0.0)
                    push(pop() / op2);
                else
                    printf("error: zero divisor\n");
                    break;
            case '\n':
                printf (n\t".8g\nn, pop ());
                break;
            default:
                printf("error: unknown command %s\n", s);
                break;
        }
    }
    return 0;
}

#define MAXVAL 100 /* maximum depth of val stack */

int sp = 0; /* next free stack position */
double val [MAXVAL]; /* value stack */
                        
/* push: push f onto value stack */
void push (double f)
{
    if (sp < MAXVAL)
    {
        val[sp++] = f; 
    }
    else
    {
        printf("error: stack full, can't push %g\n", f);
    }
}
                        
/* pop: pop and return top value from stack */
double pop (void)
{
    if (sp > 0)
        return val[--sp];
    else
    {
        printf("error: stack empty\n");
        return 0.0;
    }
}
/* COMMENTS ON PUSH () AND POP() are BELOW */
 
#define BUFSIZE 100
                        
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */

/* get a (possibly pushed back) character */
int getch (void)
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}
                        
/* push character back on input */
void ungetch (int c)
{
     if (bufp >= BUFSIZE)
     {
         printf("ungetch: too many characters\n");
     }
     else
     {
         buf[bufp++] = c;
     }
}
                        
                       
/* getop: get next operator or numeric operand */
#include <ctype.h>
                        
int getch(void);
void ungetch(int);
                    
int getop (char s[])
{
    int i, c;
                            
    while ((s[0] = c = getch()) == ' ' || c == '\t')
        ;
    s[1] = '\0';
    
    if (!isdigit(c) && c != '.') 
    {
        return c; /* not a number */
    }
    
    i = 0;
    
    if (isdigit(c)) /* collect integer part */
    {
        while (isdigit(s[++i] = c = getch())
            ;
    }
    if (c == '.') /* collect fraction part */
    {
        while (isdigit(s[++i] = c = getch())
              ;
    }
               
    s[i] = '\0';
        
    if (c != EOF)
    {
        ungetch(c);
    }
    
    return NUMBER;
}
    

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


#76738

FromAlla _ <modelling.data@gmail.com>
Date2015-11-21 00:18 -0800
Message-ID<ca38da1b-b38c-4d58-a8ca-858f26e0759f@googlegroups.com>
In reply to#76737
On Saturday, November 21, 2015 at 11:51:19 AM UTC+4, Alla _ wrote:
> > What is getch()?
> > 
> > IIRC, getch() is not part of the C standard library. 
> >
> Here is the whole program, getch and ungetch are below main function:
> 
<snip> 
please, *ignore* this message - it contains the version full of mistakes;
I have opened my not-yet-finished test file. 

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


#76930

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-11-22 14:10 -0800
Message-ID<kfnsi3x65yw.fsf@x-alumni2.alumni.caltech.edu>
In reply to#76666
Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

> On Friday November 20 2015 15:31, in comp.lang.c, "Tim Rentsch"
> <txr@alumni.caltech.edu> wrote:
>
>> James Kuyper <jameskuyper@verizon.net> writes:
>>
>>> On 11/20/2015 11:06 AM, Alla _ wrote:
>>>> Hello!
>>>>
>>>> Please, take a look at the function below.  It is from K&R.
>>>>
>>>> I dare to wonder why they use a while loop if the condition
>>>> considers only one item in the list. ...
>>>
>>> It does not.  The loop keeps executing until getch() returns
>>> something other than ' ' or '\t'.
>>>
>>>> ... Why not to use if statement?
>>>
>>> Because that would execute the getch() only once.
>>>
>>>> What is the purpose and the logic behind the while loop in this
>>>> case?
>>>>
>>>> I have accidentally found confirmation of my
>>>> concern on stackoverflow:
>>>>
>>>> QUOTE:
>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna
>>>> weep. - ammoQ
>>>>
>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>> written by the OP, it is written by K&R!  Had any rookie
>>>> programmer written code like this today, he would have been
>>>> immediately fired. - Lundin
>>>>
>>>> UNQUOTE
>>>>
>>>> Function:
>>>>
>>>> /* getop:  get next character or numeric operand */
>>>> int getop(char s[])
>>>> {
>>>>     int i, c;
>>>> /* the below while loop */
>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>         ;
>>>
>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>> code should be quite clear.  [...]
>>
>> For people who think this code snippet is clear - did you spot
>> the subtle bug?
>
> Perhaps not the subtle bug you allude to, but...
>
> What is getch()?
>
> IIRC, getch() is not part of the C standard library. 

I noticed the getch(), but chose to ignore the anomaly,
assuming getch() to be the same semantically as getchar().
The bug I'm talking about is something else.

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


#76959

FromPhilip Lantz <prl@canterey.us>
Date2015-11-22 19:00 -0800
Message-ID<MPG.30bc214448c35f27a4@news.eternal-september.org>
In reply to#76665
Tim Rentsch wrote:
> James Kuyper writes:
> > Alla _ wrote:
> >> QUOTE:
> >> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
> >>
> >> @ammoQ Indeed.  And then people still recommend K&R, I have
> >> absolutely no idea why.  Look at this horrible code, it is not
> >> written by the OP, it is written by K&R!  Had any rookie
> >> programmer written code like this today, he would have been
> >> immediately fired. - Lundin
> >>
> >> UNQUOTE
> >>
> >> Function: 
> >>
> >> /* getop:  get next character or numeric operand */
> >> int getop(char s[])
> >> {
> >>     int i, c;
> >> /* the below while loop */
> >>     while ((s[0] = c = getch()) == ' ' || c == '\t')
> >>         ;
> >
> > I disagree with ammoQ.  Once you've learned enough about C, such
> > code should be quite clear.  [...]
> 
> For people who think this code snippet is clear - did you spot
> the subtle bug?

Are you referring to the possibility that (char)EOF could equal ' '
or '\t', which would result in an infinite loop?

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


#76982

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-11-23 06:57 -0500
Message-ID<n2uuqc$7si$1@dont-email.me>
In reply to#76959
On 11/22/2015 10:00 PM, Philip Lantz wrote:
> Tim Rentsch wrote:
>> James Kuyper writes:
>>> Alla _ wrote:
>>>> QUOTE:
>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
>>>>
>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>> written by the OP, it is written by K&R!  Had any rookie
>>>> programmer written code like this today, he would have been
>>>> immediately fired. - Lundin
>>>>
>>>> UNQUOTE
>>>>
>>>> Function: 
>>>>
>>>> /* getop:  get next character or numeric operand */
>>>> int getop(char s[])
>>>> {
>>>>     int i, c;
>>>> /* the below while loop */
>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>         ;
>>>
>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>> code should be quite clear.  [...]
>>
>> For people who think this code snippet is clear - did you spot
>> the subtle bug?
> 
> Are you referring to the possibility that (char)EOF could equal ' '
> or '\t', which would result in an infinite loop?

That's only possible if CHAR_MAX > INT_MAX; but that is permitted to be
the case. As a matter of QoI, I'd recommend that EOF be chosen for such
a system so that (char)EOF doesn't match any member of the basic
character set, but it might not be possible to avoid a match to a member
of the extended character set.

To cover that possibility, you'd have to also allow breaking out of the
loop if feof() or ferror() are true.
-- 
James Kuyper

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


#77060

FromPhilip Lantz <prl@canterey.us>
Date2015-11-23 23:49 -0800
Message-ID<MPG.30bdb64836003089a9@news.eternal-september.org>
In reply to#76982
James Kuyper wrote:
> Philip Lantz wrote:
> > Tim Rentsch wrote:
> >> James Kuyper writes:
> >>> Alla _ wrote:
> >>>> QUOTE:
> >>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
> >>>>
> >>>> @ammoQ Indeed.  And then people still recommend K&R, I have
> >>>> absolutely no idea why.  Look at this horrible code, it is not
> >>>> written by the OP, it is written by K&R!  Had any rookie
> >>>> programmer written code like this today, he would have been
> >>>> immediately fired. - Lundin
> >>>>
> >>>> UNQUOTE
> >>>>
> >>>> Function: 
> >>>>
> >>>> /* getop:  get next character or numeric operand */
> >>>> int getop(char s[])
> >>>> {
> >>>>     int i, c;
> >>>> /* the below while loop */
> >>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
> >>>>         ;
> >>>
> >>> I disagree with ammoQ.  Once you've learned enough about C, such
> >>> code should be quite clear.  [...]
> >>
> >> For people who think this code snippet is clear - did you spot
> >> the subtle bug?
> > 
> > Are you referring to the possibility that (char)EOF could equal ' '
> > or '\t', which would result in an infinite loop?
> 
> That's only possible if CHAR_MAX > INT_MAX; but that is permitted to be
> the case.

I think INT_MAX == 32767, CHAR_MAX == 255, ' ' == 255 and EOF == -1
will also do it, for example.

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


#77086

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-11-24 07:13 -0500
Message-ID<n31k4g$f8k$1@dont-email.me>
In reply to#77060
On 11/24/2015 02:49 AM, Philip Lantz wrote:
> James Kuyper wrote:
>> Philip Lantz wrote:
...
>>> Are you referring to the possibility that (char)EOF could equal ' '
>>> or '\t', which would result in an infinite loop?
>>
>> That's only possible if CHAR_MAX > INT_MAX; but that is permitted to be
>> the case.
> 
> I think INT_MAX == 32767, CHAR_MAX == 255, ' ' == 255 and EOF == -1
> will also do it, for example.

I'm not sure what I was thinking when I wrote that. Possibly I wasn't
thinking :-(. Or perhaps I was thinking of EOF==' ' or '\t', rather than
(char)EOF.
-- 
James Kuyper

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


#76997

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-11-23 07:55 -0800
Message-ID<kfna8q44snw.fsf@x-alumni2.alumni.caltech.edu>
In reply to#76959
Philip Lantz <prl@canterey.us> writes:

> Tim Rentsch wrote:
>> James Kuyper writes:
>>> Alla _ wrote:
>>>> QUOTE:
>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
>>>>
>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>> written by the OP, it is written by K&R!  Had any rookie
>>>> programmer written code like this today, he would have been
>>>> immediately fired. - Lundin
>>>>
>>>> UNQUOTE
>>>>
>>>> Function: 
>>>>
>>>> /* getop:  get next character or numeric operand */
>>>> int getop(char s[])
>>>> {
>>>>     int i, c;
>>>> /* the below while loop */
>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>         ;
>>>
>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>> code should be quite clear.  [...]
>>
>> For people who think this code snippet is clear - did you spot
>> the subtle bug?
>
> Are you referring to the possibility that (char)EOF could equal ' '
> or '\t', which would result in an infinite loop?

Yes that's it.

Note by the way that the claim that this situation can occur only
if CHAR_MAX > INT_MAX isn't right.  It can occur if char is
unsigned and EOF has one of the appropriate negative values,
or if char is signed and EOF has a value less than CHAR_MIN.

To me the code has a bug not because either of those situations
is likely (which they aren't) but because it has an unobvious
implementation dependency which could cause erroneous behavior.
Also the problem is easy to code around --

    while (  s[0] = c = getch(),  c == ' ' || c == '\t'  ) ...

Now what happens with the value of the assignment to s[0] doesn't
matter, and pretty obviously doesn't matter.

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


#77058

FromPhilip Lantz <prl@canterey.us>
Date2015-11-23 23:36 -0800
Message-ID<MPG.30bdb356bb72ffb9a7@news.eternal-september.org>
In reply to#76997
Tim Rentsch wrote:
> 
> Philip Lantz <prl@canterey.us> writes:
> 
> > Tim Rentsch wrote:
> >> James Kuyper writes:
> >>> Alla _ wrote:
> >>>> QUOTE:
> >>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
> >>>>
> >>>> @ammoQ Indeed.  And then people still recommend K&R, I have
> >>>> absolutely no idea why.  Look at this horrible code, it is not
> >>>> written by the OP, it is written by K&R!  Had any rookie
> >>>> programmer written code like this today, he would have been
> >>>> immediately fired. - Lundin
> >>>>
> >>>> UNQUOTE
> >>>>
> >>>> Function: 
> >>>>
> >>>> /* getop:  get next character or numeric operand */
> >>>> int getop(char s[])
> >>>> {
> >>>>     int i, c;
> >>>> /* the below while loop */
> >>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
> >>>>         ;
> >>>
> >>> I disagree with ammoQ.  Once you've learned enough about C, such
> >>> code should be quite clear.  [...]
> >>
> >> For people who think this code snippet is clear - did you spot
> >> the subtle bug?
> >
> > Are you referring to the possibility that (char)EOF could equal ' '
> > or '\t', which would result in an infinite loop?
> 
> Yes that's it.
> 
> Note by the way that the claim that this situation can occur only
> if CHAR_MAX > INT_MAX isn't right.  It can occur if char is
> unsigned and EOF has one of the appropriate negative values,
> or if char is signed and EOF has a value less than CHAR_MIN.
> 
> To me the code has a bug not because either of those situations
> is likely (which they aren't) but because it has an unobvious
> implementation dependency which could cause erroneous behavior.
> Also the problem is easy to code around --
> 
>     while (  s[0] = c = getch(),  c == ' ' || c == '\t'  ) ...
> 
> Now what happens with the value of the assignment to s[0] doesn't
> matter, and pretty obviously doesn't matter.

Or even better,
    while (c = getch(), c == ' ' || c == '\t');
    s[0] = c;

Since the assignment to s[0] has no business being inside the loop
anyway.

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


#77280

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-11-27 13:32 -0800
Message-ID<kfnsi3ryvpi.fsf@x-alumni2.alumni.caltech.edu>
In reply to#77058
Philip Lantz <prl@canterey.us> writes:

> Tim Rentsch wrote:
>
>> Philip Lantz <prl@canterey.us> writes:
>>
>>> Tim Rentsch wrote:
>>>> James Kuyper writes:
>>>>> Alla _ wrote:
>>>>>> QUOTE:
>>>>>> Lines like while ((s[0] = c = getch()) == ' ' || c == '\t'); make me wanna weep. - ammoQ
>>>>>>
>>>>>> @ammoQ Indeed.  And then people still recommend K&R, I have
>>>>>> absolutely no idea why.  Look at this horrible code, it is not
>>>>>> written by the OP, it is written by K&R!  Had any rookie
>>>>>> programmer written code like this today, he would have been
>>>>>> immediately fired. - Lundin
>>>>>>
>>>>>> UNQUOTE
>>>>>>
>>>>>> Function: 
>>>>>>
>>>>>> /* getop:  get next character or numeric operand */
>>>>>> int getop(char s[])
>>>>>> {
>>>>>>     int i, c;
>>>>>> /* the below while loop */
>>>>>>     while ((s[0] = c = getch()) == ' ' || c == '\t')
>>>>>>         ;
>>>>>
>>>>> I disagree with ammoQ.  Once you've learned enough about C, such
>>>>> code should be quite clear.  [...]
>>>>
>>>> For people who think this code snippet is clear - did you spot
>>>> the subtle bug?
>>>
>>> Are you referring to the possibility that (char)EOF could equal ' '
>>> or '\t', which would result in an infinite loop?
>>
>> Yes that's it.
>>
>> Note by the way that the claim that this situation can occur only
>> if CHAR_MAX > INT_MAX isn't right.  It can occur if char is
>> unsigned and EOF has one of the appropriate negative values,
>> or if char is signed and EOF has a value less than CHAR_MIN.
>>
>> To me the code has a bug not because either of those situations
>> is likely (which they aren't) but because it has an unobvious
>> implementation dependency which could cause erroneous behavior.
>> Also the problem is easy to code around --
>>
>>     while (  s[0] = c = getch(),  c == ' ' || c == '\t'  ) ...
>>
>> Now what happens with the value of the assignment to s[0] doesn't
>> matter, and pretty obviously doesn't matter.
>
> Or even better,
>     while (c = getch(), c == ' ' || c == '\t');
>     s[0] = c;
>
> Since the assignment to s[0] has no business being inside the loop
> anyway.

Yes, I saw that idea in another posting.  I didn't bring it up
because my point was only about the expression, not about the
loop as a whole.  For didactic reasons I try avoid muddying
the waters.

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


#76675

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-11-20 16:13 -0500
Message-ID<n2o2aa$q25$1@dont-email.me>
In reply to#76653
On 11/20/2015 12:15 PM, James Kuyper wrote:
> [...]
>      while((c=getch()) == ' ' || c == '\t');
>      s[0] = c;
>
> The reason they put the ';' on a separate line is to make it more
> visible - they're worried that writing loops with empty bodies the way I
> prefer to write them will result in people not noticing the ';' and
> correspondingly misinterpret the code. However, I often write loops with
> active loop conditions (ones that can change the state of the program)
> and empty bodies, and as a result I always pay close attention to a ';'
> in that location. I'm quite error-prone in general, yet I can't remember
> ever making the kind of mistake they're worrying about.

     FWIW, I've adopted a different convention:

	while ((c = getch()) == ' ' || c == '\t')
	    continue;

It makes no difference to the meaning of the code, nor to the
compiler, but it makes the vacuous loop body more visible.  IMHO.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

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


#76925

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-11-22 13:54 -0800
Message-ID<kfna8q57l9k.fsf@x-alumni2.alumni.caltech.edu>
In reply to#76675
Eric Sosman <esosman@comcast-dot-net.invalid> writes:

> On 11/20/2015 12:15 PM, James Kuyper wrote:
>> [...]
>>      while((c=getch()) == ' ' || c == '\t');
>>      s[0] = c;
>>
>> The reason they put the ';' on a separate line is to make it more
>> visible - they're worried that writing loops with empty bodies the way I
>> prefer to write them will result in people not noticing the ';' and
>> correspondingly misinterpret the code.  However, I often write loops with
>> active loop conditions (ones that can change the state of the program)
>> and empty bodies, and as a result I always pay close attention to a ';'
>> in that location.  I'm quite error-prone in general, yet I can't remember
>> ever making the kind of mistake they're worrying about.
>
>     FWIW, I've adopted a different convention:
>
>     while ((c = getch()) == ' ' || c == '\t')
>         continue;
>
> It makes no difference to the meaning of the code, nor to the
> compiler, but it makes the vacuous loop body more visible.  IMHO.

I suggest  do {} while(...);

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


#76663

FromGeoff <geoff@invalid.invalid>
Date2015-11-20 12:19 -0800
Message-ID<phuu4bl5s5gosihc6mca0pq6g2r2ghp949@4ax.com>
In reply to#76641
On Fri, 20 Nov 2015 08:06:59 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:

>Hello!
>
>Please, take a look at the function below. It is from K&R.
>
>I dare to wonder why they use a while loop if the condition
>considers only one item in the list. Why not to use if statement?
>What is the purpose and the logic behind the while loop in this case?
>

Follow Richard Heathfield's advice. Slow down. 

I would even say go back to chapter 1 and type in each example and
play with it, grasp the concepts and break the examples and see why
they break. Often the examples build on prior examples so following
the book and building the code creates a library of examples to which
you can refer later in your career.

You say you're on a Mac. What OS X version do you run? Have you
installed the free Xcode IDE? This is an excellent tool for testing
your code and stepping through it in the debugger. It has its own
learning curve and some of the icons are non-intuitive but it's
certainly better for a novice learning the language than gdb and
command-line compiles. It also gets you started on the path of using
contemporary IDEs for development if that is your career goal.

Keep in mind also that "The C Programming Language" 2nd Edition is an
expression of the state of the language as it was in 1988 by the
masters of and inventors of the language. They often chose to express
certain concepts and nuances of the language in the examples in order
to show the idioms and expressiveness of the language without
necessarily writing a lot of text about it. The master forces the
student to stretch his mind and grasp the concept without having to be
told, "Hey, this is important." When learning a technical subject, you
have to stop, think, absorb and toy with the concepts being taught.

Michelangelo never explained every detail of how he carved the statue
of David, he simply said he removed the stone that wasn't David.

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


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

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


csiph-web