Home > front end >  Why does getchar() give \n even though the buffer is empty?
Why does getchar() give \n even though the buffer is empty?

Time:05-27

I have the following function that should loop and take multiple lines from the user (names and dates). The user needs to enter an empty line to stop the loop.

 while ((line = getLineFromUser()) != NULL) {
    token = getNameAndDate(&concert, line);

however, when I get to the last line in the loop, the getchar() waits for the user input (which is good for me, because it means that I finished getting the previous line), but ch gets '\n' as soon as I enter the next line (not specifically an empty line). as anyone encountered this before? Everything else seems to work fine until the last getchar(). if needed, I will provide the other functions as well.

this is the getLineFromUser function:

char *getLineFromUser() {
    int ch;
    char *line;

    int logSize, phySize;
    logSize = 0, phySize = 2;
    line = (char *)malloc(sizeof(char) * phySize);
    checkAllocation(line);

    while ((ch = getchar()) != '\n' && ch != EOF) {
        if (logSize == phySize) {
            phySize *= 2;
            line = (char *)realloc(line, sizeof(char) * phySize);
            checkAllocation(line);
        }
        line[logSize] = ch;     // get char into the str
        logSize  ;
    }
    if (logSize == 0) {
        free(line);
        line = NULL;
    } else {
        line = realloc(line, sizeof(char) * logSize   1);
        checkAllocation(line);
        line[logSize] = '\0';
    }
    return line;
}

and this is the declaration:

char* getLineFromUser();

CodePudding user response:

I would suggest revising your getLineFromUser function slightly so that you can call it more like this:

char *line, *token;
    
while ((line = getLineFromUser()) != NULL) {
    if(is_empty(line)) break;
    token = getNameAndDate(line);
}

Trying to treat the newlines separately from the lines is a recipe for complexity, confusion, and bugs.

CodePudding user response:

Your code seems fine except for these remarks:

  • line = realloc(line, sizeof(char) * logSize 1); is inconsistent: you should either write realloc(line, logSize 1) or realloc(line, sizeof(char) * (logSize 1)). There is no consequence here since sizeof(char) is 1 by definition.

  • you return NULL at end of file and for an empty line, so the caller cannot tell the difference. This might be a problem elsewhere in the code.

The main loop should stop as soon as an empty line is entered, or at end of file:

while ((line = getLineFromUser()) != NULL) {
    token = getNameAndDate(&concert, line);
}

You did not post the rest of the calling function: it should not have ch = getchar(); before nor after this loop.

  • Related