0

In K&R, at the beginning of chapter 5, is presented the function getint that

performs free-format input conversion by breaking a stream of charachters into integer values, one integer per call.

The function is pretty simple, but i can't actually understand why is c pushed back in to the buffer in the first if-statement. Because of this, every time you call getint it will do the same thing. Because it will read the next charachter in the buffer, which is c. Is this strategy intended to be a kind of security mechanism?

int getint(int *pn) {
    int c, sign;
    while(isspace(c = getch()))
        ;
    if(!isdigit(c) && c != EOF && c != '+' && c != '-') {
        ungetch(c);
        return 0;
    }

    sign = (c == '-') ? -1 : 1;
    if(c == '+' || c == '-')
        c = getch();

    for(*pn = 0; isdigit(c); (c = getch()))
        *pn = 10 * *pn + (c - '0');
    *pn *= sign;
    if(c != EOF)
        ungetch(c);
    return c;

}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
cristid9
  • 1,070
  • 1
  • 17
  • 37
  • possible duplicate of [What is the purpose of ungetc (or ungetch from K&R)?](http://stackoverflow.com/questions/476615/what-is-the-purpose-of-ungetc-or-ungetch-from-kr) – ecatmur Jan 29 '14 at 15:20
  • @ecatmur: This is not a duplicate of that. This question asks why `ungetch` is being used, not what it does. – Eric Postpischil Jan 29 '14 at 15:37
  • @EricPostpischil "what is the purpose of" and "why is it used" seem the same question to me. Your answer covers the same ground as the accepted answer to that question. – ecatmur Jan 29 '14 at 15:42
  • @ecatmur: The purpose of `ungetch` is to push a character onto the head of a stream, which enables “peeking” at a character without altering the stream (because the only mechanisms for “peeking”, such as `getch` alter the stream by removing a character). The OP of this question understands that. They do not understand why the code was doing that. They are asking about the larger purpose of this code, not the mechanism of `ungetch`. – Eric Postpischil Jan 29 '14 at 15:49

1 Answers1

1

The code you ask about causes getint to stop if the next character in the stream is not part of a numeral (or a space) because it is not a digit or sign character.

The notion is that as long as you call getint while there are acceptable numerals in the input, it will convert those numerals to int values and return them. When you call getint while there is not an acceptable numeral next in the input, it will not perform a conversion. Since it is not performing a character, it leaves the character it is not using in the stream.

A proper routine would return an error indication so the caller can easily determine that getint is not performing a conversion for this reason. As it is, the caller cannot distinguish between getint returning 0 for a “0” in the input and getint returning 0 for a non-numeral in the input. However, as this is only tutorial code, features like this are omitted.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312