K&R 5-10

Discussion in 'C Programming' started by mdh, Apr 16, 2007.

  1. mdh

    mdh Guest

    I wonder if I could ask for help. I have been struggling with this
    most of the day, and cannot understand what is going on. The problems
    are (1) it does not work!! (but exits normally on compilation...and
    (2) when stepped through ( I use Xcode) it crashes without any error
    message, at the indicated function. I have dissected it, run
    individual parts on their own...which seem to work fine. Thanks in
    advance.
    I have supplied 3 command line arguments ( 22.3, 11.9, and '+' so the
    argc is 4).
    I am including the full code, as there are probably a lot I am missing
    and messing up.
    >>>>>>>>>>>


    #include <stdio.h>
    #include <math.h>


    #define MAXOP 100
    #define NUMBER 0

    int getop(char *);
    void ungets( char *);
    void push(double);
    double pop( void);


    int main ( int argc, char *argv[]){

    char s[MAXOP];
    double op2;

    while ( --argc > 0){
    ungets(" ");
    ungets(*++argv);
    switch(getop(s)){
    case NUMBER:
    push(atof(s));
    break;
    case '+':
    push(pop() + pop());
    break;
    default:
    printf("Error: Unknown input");
    break;

    }

    }
    printf("\t %.8g", pop());
    return 0;
    }

    /*********/
    #define MAXSTACK 50
    double static stack[MAXSTACK];
    int static stkp=0;

    double pop(void){

    if ( stkp > 0)

    return stack[--stkp];

    else{
    printf("Error: Stack empty");
    return 0.00;
    }

    }

    void push(double i){

    if (stkp < MAXSTACK)
    stack[stkp++]=i;
    else
    printf("Error: Stack overflow");
    }

    /**********/
    #include <string.h>
    void ungetch( int );


    void ungets( char *s){ /*** I think the problem is here ***/
    int i;
    i=strlen(s);
    while ( i > 0)
    ungetch(s[--i]);
    }


    /**********/

    # define MAXBUF 25
    char buf[MAXBUF];
    static int bufp=0;

    void ungetch( int c ){
    if (bufp < MAXBUF)
    buf[bufp++]=c;
    else
    printf("Error: Ungetch buffer overflow");
    }

    int getch(void){

    return ( (bufp==0) ? getch(): buf[--bufp]);

    }

    #include <ctype.h>
    int getch(void);

    int getop(char *s){
    int c;

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

    if ( !isdigit(c) && c != '.'){

    return c; /** c is not a number **/

    if ( isdigit(c))
    while ( isdigit(*s++=c=getch()));

    if ( c == '.')
    while ( isdigit(*s++=c=getch()));
    *s='\0';

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

    return NUMBER;
    }




    return 0;

    }
    mdh, Apr 16, 2007
    #1
    1. Advertising

  2. mdh wrote:
    > I wonder if I could ask for help. I have been struggling with this
    > most of the day, and cannot understand what is going on. The problems
    > are (1) it does not work!! (but exits normally on compilation...and
    > (2) when stepped through ( I use Xcode) it crashes without any error
    > message, at the indicated function. I have dissected it, run
    > individual parts on their own...which seem to work fine. Thanks in
    > advance.
    > I have supplied 3 command line arguments ( 22.3, 11.9, and '+' so the
    > argc is 4).
    > I am including the full code, as there are probably a lot I am missing
    > and messing up.

    [snip]

    >


    > int getop(char *s){
    > int c;
    >
    > while( (c=s[0]=getch()) == " " || c == '\t');
    > s[1] = '\0';
    >
    > if ( !isdigit(c) && c != '.'){

    -------------------------------^
    Are you sure this is correct? Doesn't look right to me.


    >
    > return c; /** c is not a number **/
    >
    > if ( isdigit(c))
    > while ( isdigit(*s++=c=getch()));



    >
    > if ( c == '.')
    > while ( isdigit(*s++=c=getch()));
    > *s='\0';
    >
    > if ( c != EOF)
    > ungetch(c);
    >
    > return NUMBER;
    > }
    >
    >
    >
    >
    > return 0;
    >
    > }
    >



    HTH
    Bjørn
    =?ISO-8859-1?Q?Bj=F8rn_Augestad?=, Apr 16, 2007
    #2
    1. Advertising

  3. mdh

    mdh Guest

    Re: K&R 5-10

    On Apr 15, 11:22 pm, Bjørn Augestad <> wrote:

    > >
    > > int getop(char *s){
    > > int c;

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

    >
    > > if ( !isdigit(c) && c != '.'){

    >
    > -------------------------------^
    > Are you sure this is correct? Doesn't look right to me.



    I have taken most of it from K&$R and from Tondo and Gimpel. I am not
    sure at this stage what is going on, so you may well be correct, but I
    think it is correct.
    mdh, Apr 16, 2007
    #3
  4. Re: K&R 5-10

    mdh wrote:
    > On Apr 15, 11:22 pm, Bjørn Augestad <> wrote:
    >
    >>> int getop(char *s){
    >>> int c;
    >>> while( (c=s[0]=getch()) == " " || c == '\t');
    >>> s[1] = '\0';
    >>> if ( !isdigit(c) && c != '.'){

    >> -------------------------------^
    >> Are you sure this is correct? Doesn't look right to me.

    >
    >
    > I have taken most of it from K&$R and from Tondo and Gimpel. I am not
    > sure at this stage what is going on, so you may well be correct, but I
    > think it is correct.
    >



    My point(maybe lost due to font issues) was that you probably have a
    block where you just wanted a single statement.

    Here's the code for getop(), reformatted by me.

    int getop(char *s)
    {
    int c;

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

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

    /* THIS CODE IS NEVER EXECUTED */
    if ( isdigit(c))
    while ( isdigit(*s++=c=getch()));

    if ( c == '.')
    while ( isdigit(*s++=c=getch()));

    *s='\0';

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

    return NUMBER;
    }

    return 0;
    }

    Do you see how getop() never returns NUMBER?

    BTW, if you think that your problem is related to ungetch(), why not
    check the return value from ungetch()?
    =?ISO-8859-1?Q?Bj=F8rn_Augestad?=, Apr 16, 2007
    #4
  5. mdh

    pete Guest

    Re: K&R 5-10

    Bjørn Augestad wrote:

    > Here's the code for getop(), reformatted by me.
    >
    > int getop(char *s)
    > {
    > int c;
    >
    > while( (c=s[0]=getch()) == " " || c == '\t');
    > s[1] = '\0';


    That's a bad format.
    It almost looks like the assignment to s[1] is in the loop.

    --
    pete
    pete, Apr 16, 2007
    #5
  6. Re: K&R 5-10

    pete wrote:
    > Bjørn Augestad wrote:
    >
    >> Here's the code for getop(), reformatted by me.
    >>
    >> int getop(char *s)
    >> {
    >> int c;
    >>
    >> while( (c=s[0]=getch()) == " " || c == '\t');
    >> s[1] = '\0';

    >
    > That's a bad format.
    > It almost looks like the assignment to s[1] is in the loop.
    >


    Well spotted, Pete. I missed that ugliness in the original code.
    Now that I had another look at that line, I spotted yet another bug.
    Note how the OP compares c with " " instead of ' '. I know nothing about
    Xcode, but someone should adjust the warning level of their compiler.

    Bjørn
    =?ISO-8859-1?Q?Bj=F8rn_Augestad?=, Apr 16, 2007
    #6
  7. mdh

    pete Guest

    Re: K&R 5-10

    Bjørn Augestad wrote:
    >
    > pete wrote:
    > > Bjørn Augestad wrote:
    > >
    > >> Here's the code for getop(), reformatted by me.
    > >>
    > >> int getop(char *s)
    > >> {
    > >> int c;
    > >>
    > >> while( (c=s[0]=getch()) == " " || c == '\t');
    > >> s[1] = '\0';

    > >
    > > That's a bad format.
    > > It almost looks like the assignment to s[1] is in the loop.
    > >

    >
    > Well spotted, Pete. I missed that ugliness in the original code.
    > Now that I had another look at that line, I spotted yet another bug.
    > Note how the OP compares c with " " instead of ' '.


    Oh my!

    > I know nothing about Xcode,
    > but someone should adjust the warning level of their compiler.


    Yes.

    --
    pete
    pete, Apr 16, 2007
    #7
  8. mdh

    pete Guest

    mdh wrote:

    > static int bufp=0;


    > int getch(void){
    >
    > return ( (bufp==0) ? getch(): buf[--bufp]);
    >
    > }


    If bufp equals zero when getch is called,
    then getch will never return.

    --
    pete
    pete, Apr 16, 2007
    #8
  9. mdh

    mdh Guest

    Re: K&R 5-10

    On Apr 16, 5:45 am, pete <> wrote:

    > > Note how the OP compares c with " " instead of ' '.



    Thanks...I missed that. The problem was that I was not able to get
    there as the debugger kept on crashing. It turns out that the project
    had become corrupted. Taking the program, and inserting it into a new
    project solved the issue. I have to say I have not experienced this
    before, but I guess this is old hat to the more experienced
    programmers.


    One other issue that came up was this. Tondo and Gimpel had used
    <math.h> for the lib function "atof". Atof did not work. When I
    changed the include to <stdlib.h> ( as done in K&R) atof performed as
    planned. My question is this. What did the compiler then do with the
    atof function when the includes was incorrect? The conversion did not
    make any sense at all, but it still gave some figure.

    Thank you for your help, as usual.
    mdh, Apr 16, 2007
    #9
  10. mdh

    pete Guest

    Re: K&R 5-10

    mdh wrote:
    >
    > On Apr 16, 5:45 am, pete <> wrote:
    >
    > > > Note how the OP compares c with " " instead of ' '.

    >
    > Thanks...I missed that. The problem was that I was not able to get
    > there as the debugger kept on crashing. It turns out that the project
    > had become corrupted. Taking the program, and inserting it into a new
    > project solved the issue. I have to say I have not experienced this
    > before, but I guess this is old hat to the more experienced
    > programmers.
    >
    > One other issue that came up was this. Tondo and Gimpel had used
    > <math.h> for the lib function "atof".


    That's pathetic.

    > Atof did not work. When I
    > changed the include to <stdlib.h> ( as done in K&R) atof performed as
    > planned. My question is this. What did the compiler then do with the
    > atof function when the includes was incorrect?


    For cases of undefined behavior, like that,
    the compiler is allowed to do whatever it wants to do.

    > The conversion did not
    > make any sense at all, but it still gave some figure.


    --
    pete
    pete, Apr 16, 2007
    #10
  11. mdh

    mdh Guest

    Re: K&R 5-10

    On Apr 16, 12:26 pm, pete <> wrote:
    > mdh wrote:
    >
    >
    >
    > For cases of undefined behavior, like that,
    > the compiler is allowed to do whatever it wants to do.
    >

    Apparently so. Thanks for your input. T&G have been pretty good up to
    now...perhaps atof was moved? This is the first mistake I have seen
    them make.
    mdh, Apr 16, 2007
    #11
  12. mdh

    CBFalconer Guest

    Re: K&R 5-10

    pete wrote:
    > Bjørn Augestad wrote:
    >
    >> Here's the code for getop(), reformatted by me.
    >>
    >> int getop(char *s)
    >> {
    >> int c;
    >>
    >> while( (c=s[0]=getch()) == " " || c == '\t');
    >> s[1] = '\0';

    >
    > That's a bad format.
    > It almost looks like the assignment to s[1] is in the loop.


    It has insufficient blanks and parens and 's, excessive "s, for
    readability. Try:

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

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>
    <http://www.aaxnet.com/editor/edit043.html>

    "A man who is right every time is not likely to do very much."
    -- Francis Crick, co-discover of DNA
    "There is nothing more amazing than stupidity in action."
    -- Thomas Matthews



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Apr 17, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page