getchar() prompting for input when typing space before Enter

70 views Asked by At

A part of the code I'm writing has to read a sequence of integers separated by a space from input into an array.

It works fine when I input, for example, 3 numbers, and then press Enter. But if after inputting the numbers I press Space and then Enter, it goes to new line and waits for me to input more numbers.

How can I avoid this?

#include <stdio.h>
#include <stdbool.h>

#define MAX_VALUES 250000

int main() 
{
    int sequence[MAX_VALUES];
    int count = 0;
    do {
        scanf("%d", &sequence[count++]);
    }
    while(getchar() != '\n');

    for(int i = 0; i < count; i++) {
        printf("Element is: %d\n", sequence[i]);
    }

    return 0;
}
2

There are 2 answers

0
ChrisB On

Just think about what your code does, e.g. for the following input: 1 \n.

  • scanf consumes 1
  • getchar consumes
  • now, scanf sees \n and will wait until a number arrives.

That is why you are seeing this undesired behavior.

A simple way to fix this would be to check for and skip spaces after each scanf:

#include <stdio.h>

#define MAX_VALUES 250000

int main() 
{
    int sequence[MAX_VALUES];
    int count = 0;
    char c;

    do {
         scanf("%d", &sequence[count++]);
         do {
             c = getchar();
         } while (c == ' ');
    } while (c != '\n');

    for (int i = 0; i < count; i++) {
        printf("Element is: %d\n", sequence[i]);
    }
}
0
Nierusek On

Another answer has already answered why your program doesn't work, so I will not cover that. But I think there is another solution to this problem. You can first read the whole line, and then use sscanf to extract integers:

#include <stdio.h>
#include <stdbool.h>

#define MAX_VALUES 250000

/* You don't want to declare such big arrays inside functions.
   Make them global or use malloc */
char line[MAX_VALUES * 10];
int sequence[MAX_VALUES]; 

int main() 
{
    int ret = 0, len;
    size_t count = 0, off = 0; // I recommend using size_t for indexing
    /* scanf reads the whole line (there are better ways to do this,
       but I want to keep it simple) */
    scanf("%[^\n]", line);
    while ((ret = sscanf(line + off, "%d%n", &sequence[count++], &len)) != EOF) {
        off += len;
    }
    --count;

    for(int i = 0; i < count; i++) {
        printf("Element is: %d\n", sequence[i]);
    }

    return 0;
}