cungetc

understanding ungetc use in a simple getword


I've come across such an example of getword. I understand all the checks and etc. but I have a problem with ungetc.

When the c does satisfy if ((!isalpha(c)) || c == EOF)and also doesn't satisfy while (isalnum(c)) -> it isn't a letter, nor a number - ungetc rejects that char.

Let's suppose it is '\n'.

Then it gets to return word however it can't be returned since it is not saved in any array. What happens then?

    while (isalnum(c)) {
        if (cur >= size) {
            size += buf;
            word = realloc(word, sizeof(char) * size);

        }
        word[cur] = c;
        cur++;
        c = fgetc(fp);
    }
    if ((!isalpha(c)) || c == EOF) {
        ungetc(c, fp);          
    }
    return word;

EDIT @Mark Byers - thanks, but that c was rejected for a purpose, and will not satisfy the condition again and again in an infinite loop?


Solution

  • The terminal condition, just before the line you don't understand, is not good. It should probably be:

    int c;
    
    ...
    
    if (!isalpha(c) && c != EOF)
        ungetc(c, fp);
    

    This means that if the last character read was a real character (not EOF) and wasn't an alphabetic character, push it back for reprocessing by whatever next uses the input stream fp. That is, suppose you read a blank; the blank will terminate the loop and the blank will be pushed back so that the next getc(fp) will read the blank again (as would fscanf() or fread() or any other read operation on the file stream fp). If, instead of blank, you got EOF, then there is no attempt to push back the EOF in my revised code; in the original code, the EOF would be pushed back.

    Note that c must be an int rather than a char.