Search code examples
cscopestdingetchar

What unobvious conditions can dictate how long getchar has access to newline characters after input is provided?


I have two functions both of which take input from using getchar.

Example1() is intended to gather input and return the value. However, when called twice in a row this function registers the newline character submitted from the previous call to getchar. This doesn't make sense to me because I would have thought that getchar would be limited to the actual scope of where it was called, ending when the function itself ends.

int Example1()
{
    printf("Gather input from example1\n");

    int user_input;
    while ((user_input = getchar()) != '\n')
    {
        return user_input;
    }

    return 0;
}

Example2() gathers input storing it in a newly created struct member. When called twice this function doesn't produce the same issue that the first function does.

struct foo *Example2()
{

    struct foo *user= (struct foo*) malloc(sizeof(struct foo));
    
    printf("Gather input from example2\n");

    int user_input
    while ((user_input = getchar()) != '\n') 
    { 
        user->user_input= user_input;
    }
    
    return user;
}

I thought that when the function returns the actual buffer for getchar would be gone with the scope of that function call. What would cause the newline character to be kept in the stdin buffer in the Example1() function, but not in the Example2() function?

Full Code:

#include<stdlib.h>
#include<stdio.h>

struct foo {
    char user_input;
};

struct foo *Example2()
{

    struct foo *user= (struct foo*) malloc(sizeof(struct foo));
    
    printf("Gather input from example2\n");

    int user_input;
    while ((user_input = getchar()) != '\n') 
    { 
        user->user_input= user_input;
    }
    
    return user;
}

int Example1()
{
    printf("Gather input from example1\n");

    int user_input;
    while ((user_input = getchar()) != '\n')
    {
        return user_input;
    }

    return 0;
}

int main()
{
    struct foo *user = Example2();
    printf("Example 2 function user_input 1/2 : %d\n", user->user_input);
    
    struct foo *user2 = Example2();
    printf("Example 2 function user_input 2/2 : %d\n", user2->user_input);

    printf("Example 1 function user_input 1/2 : %d\n", Example1());
    printf("Example 1 function user_input 2/2 : %d\n", Example1());
}

Solution

  • getchar() reads one character from the buffer. The buffer is dependent of function scopes.

    In your Example1 function, return statement is executed after getchar() is called once (regardless of whether the character read is newline or not). Therefore, only one character is read by one call of Example1 and it may be only part of a line. If Example1 read only part of a line, the left part of line will be read by subsequent calls of getchar() (or other stdin-reading functions).

    On the other hand, in your Example2 function, there are no return statement in the loop and getchar() is executed until newline character is read. (even if EOF is reached!) Therefore, Example2 will read until end of one line by one call.