Thread: getch and ungetch functions Unable to understand

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    13

    getch and ungetch functions Unable to understand

    Code:
    #include <stdio.h>
    
    #define BUFSIZE 100
    
    int getch(void);
    void ungetch(int c);
    
    int buf[BUFSIZE]; /* buffer for ungetch */
    int bufp = 0;     /* next free position in buf */
    
    int main(void)
    {
        int i = 0;
        char ch;
        puts("Input an integer followed by a char:");
        /* read chars until non digit or EOF */
        while ((ch = getch()) != EOF && isdigit(ch))
            i = 10 * i + ch - 48; /* convert ASCII into int value */
    
            /* if non digit char was read, push it back into input buffer */
        if (ch != EOF)
            ungetch(ch);
    
        printf("\n\ni = %d, next char in buffer = %c\n", i, getch());
        return 0;
    }
    
    /* getch: get a (possibly pushed back) character */
    int getch(void)
    {
        return (bufp > 0) ? buf[--bufp] : getchar();
    }
    
    /* ungetch: push a character back onto the input */
    void ungetch(int c)
    {
        if (bufp >= BUFSIZE)
            printf("ungetch: too many characters \n");
        else
            buf[bufp++] = c;
    }
    Can someone explains what this getch ungetch do? I tried to understand but I am really unable to get what is going on. What I see is if I write 12a, it will always assign 1 to ch, the first character of 12a for line 17 in codes which is ch=getch() which means that there should be a problem here. But this code works. So, I am unable to get what is going on... Thanks.
    Last edited by sleftar; 11-16-2015 at 12:11 AM.

  2. #2
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Before explaining, I think that you're missing some brackets.

    Code:
    int main(void)
    {
        int i = 0;
        char ch;
        puts("Input an integer followed by a char:");
        /* read chars until non digit or EOF */
        while ((ch = getch()) != EOF && isdigit(ch)) {
            i = 10 * i + ch - 48; /* convert ASCII into int value */
    
            /* if non digit char was read, push it back into input buffer */
            if (ch != EOF)
                ungetch(ch);
        }
        printf("\n\ni = %d, next char in buffer = %c\n", i, getch());
        return 0;
    }
    /* .... */
    Edit:

    See if this changes your understanding of how things are working, and if it then works at you expected it to.

    As a side-note, the if (ch != EOF) is not required (if it really does belong in the loop as I suspect it does), because the compound statement (the bit enclosed in { }) is never executed if ch == EOF (according to the condition in the while).
    Last edited by Hodor; 11-16-2015 at 12:04 AM.

  3. #3
    Registered User
    Join Date
    Jan 2014
    Posts
    13
    Quote Originally Posted by Hodor View Post
    Before explaining, I think that you're missing some brackets.
    This code is a copy paste from a website and it works as expected. I guess indentations are not correctly placed. While loop in line 17 seems to have only one line body... Lemme correct it above so you can check again. When you compile this program it works without any problem.

    Edit: Actually i did not get why that line 21 is needed... Because it should be included in while loop and you dont need if statement because that loop already has that condition. But when I put braces for while loop, it takes input, goes to next line and does not accept any other input or does not return any output when I execute the program. program Pretty much stuck on next line.
    Last edited by sleftar; 11-16-2015 at 12:18 AM.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Hmm, I see your point. I may have been incorrect.

    Edit: Actually I was. Sorry

  5. #5
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    I was trying to think of a way to explain, but perhaps it might be easier for you to actually see what's happening. You just need to place some printf()'s in various places...

    An example:

    Code:
    #include <stdio.h>
    
    #define BUFSIZE 100
    
    int getch(void);
    void ungetch(int c);
    
    int buf[BUFSIZE]; /* buffer for ungetch */
    int bufp = 0;     /* next free position in buf */
    
    int main(void)
    {
        int i = 0;
        char ch;
        puts("Input an integer followed by a char:");
        /* read chars until non digit or EOF */
        while ((ch = getch()) != EOF && isdigit(ch)) {
            i = 10 * i + ch - 48; /* convert ASCII into int value */
            printf("  >> Inside while body. i is %d and ch is %c\n", i, ch);
        }
        
        /* if non digit char was read, push it back into input buffer */
        if (ch != EOF) {
            printf("> Got a character (%c) that we didn't want yet because it wasn't a digit. Store it in our buffer for later\n", ch);
            ungetch(ch);
        }
    
        printf("\n\ni = %d, next char in buffer = %c\n", i, getch());
        return 0;
    }
    
    /* getch: get a (possibly pushed back) character */
    int getch(void)
    {
        printf("    >>> Inside getch(). The buffer has %d characters in it.\n", bufp);
        if (bufp == 0)
            printf("    >>> Inside getch(). Getting the character using getchar()\n");
        else
            printf("    >>> Inside getch(). Getting the character from the buffer\n");
        
        return (bufp > 0) ? buf[--bufp] : getchar();
    }
    
    /* ungetch: push a character back onto the input */
    void ungetch(int c)
    {
        if (bufp >= BUFSIZE)
            printf("ungetch: too many characters \n");
        else
            buf[bufp++] = c;
    }

  6. #6
    Registered User
    Join Date
    Jan 2014
    Posts
    13
    To be honest I got nothing from this. I know how to convert a string into an integer I have no problem with it..

    When I enter 12a

    1) ch=1
    i = 10 * i + ch - 48;
    i = 10 * 0 + '1' - '0'
    i=1

    if(ch!=EOF)
    ungetch(ch);
    so ch='1' and it satisfies the above condition then it will go to ungetch(ch)
    ch='1'=49

    void ungetch(int c)

    c=49
    bufp=0
    else statement will be executed.
    buf[0]=c=49
    because of bufp++
    bufp=1 now

    2) ch=getch() means that it will execute getch() function

    return (bufp > 0) ? buf[--bufp] : getchar();
    since bufp=1>0
    it will return
    return buf[--bufp]
    which means that
    return buf[0]

    ch=buf[0]=49='1'

    So same cycle should continue over and over. But it does not work like that and I did not understand it.

  7. #7
    Registered User
    Join Date
    Jan 2014
    Posts
    13
    Nevermind I guess I was stuck at that part too.. That wrong indentation mislead me and I was thinking from other way... Now I can understand it.. Thanks.

  8. #8
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by sleftar View Post
    To be honest I got nothing from this.
    For my own understanding, how didn't it help? Did you run it?

  9. #9
    Registered User
    Join Date
    Jan 2014
    Posts
    13
    Hey there. Now I got it. There is no problem with the code. I was thinking like you in the beginning as well. I thought that while loop has more than one line as its body. But apparently it has only a single line body. After that I could figure out what is really going on..

    But can you tell me the reason of using this kind of thing in a program.. Why do we use getch and ungetch functions here. Ungetch stores the characters other than digit characters but what is the reason of using these functions. Thanks you

    This is actually a simplified version of a program in k&r (not really simplified but simplified in a way to understand just these 2 functions). And in k&r c programming language book, these 2 exactly same functions were used for a program called, reverse polish notation calculator. I was working on this program to understand what these getch and ungetch functions do.
    Last edited by sleftar; 11-16-2015 at 11:01 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unable to overload functions
    By Dave11 in forum C++ Programming
    Replies: 17
    Last Post: 05-19-2014, 04:12 AM
  2. Unable to understand CreateFile function.
    By freiza in forum C Programming
    Replies: 7
    Last Post: 10-29-2011, 02:49 PM
  3. chapter 4 K&R, getch() and ungetch()
    By blob84 in forum C Programming
    Replies: 1
    Last Post: 04-28-2011, 04:38 AM
  4. ungetch()
    By 0927 in forum C++ Programming
    Replies: 1
    Last Post: 01-16-2002, 10:35 PM
  5. differences between getch(), getche(), and ungetch()
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 01-08-2002, 02:08 AM