2

The code is attached.

int main{
    int i, n;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");
    scanf_s("%d", &n);
    getchar();

    for (i = 1; i <= n; i++) {
        printf("%10d%10d\n", i, i * i);
        if (i % 24 == 0) {
            printf("Press Enter to continue...");
            while (getchar() != '\n')
                ;
        }
    }

    return 0;
}

The code is to pause after outputting 24 squares and continue after pressing the enter.

I'm curious about the use of getchar() after the scanf_s("%d", &n). If I delete it, the second 24 squares will be printed automatically without pressing the enter. What is the reason behind it?

  • 2
    For line-based input, `fgets` should be used and the resulting buffer should be parsed afterwards. The `scanf` function is pretty limited, but it seems to be very popular in teaching students how to deal with user input. And then with teaching them poor ways of dealing with undesirable side effects. That is very unfortunate. – Cheatah Aug 23 '22 at 06:38
  • 2
    `scanf_s` is an optional part of C that most compilers do not implement. Avoid `_s` functions if you can. – n. m. could be an AI Aug 23 '22 at 06:44
  • It chews up line feed characters left behind in stdin and that's about it. – Lundin Aug 23 '22 at 06:58

1 Answers1

3

When you read with scanf, only the characters that are part of the integer are extracted from the input buffer. It stops extracting characters when it encounters anything that doesn't look like it's part of an integer value (e.g. a newline). That character remains in the input buffer until next read.

The getchar is therefore removing that character, except here it's a bit naive. For example, if you typed a value and then pressed something else before you pressed enter then that character will be discarded and the enter will still be waiting.

You would be better off at least using the same approach as the loop:

scanf_s("%d", &n);
while (getchar() != '\n');

Better still, put that in a function like ignore_to_end_of_line() which can do this and maybe check for other things like EOF.

#include <stdio.h>

void ignore_to_end_of_line()
{
    int c;
    do {
        c = getchar();
    } while (c != EOF && c != '\n');
}

int main(void)
{
    int i, n;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");

    if (1 != scanf_s("%d", &n))
        return 1;

    ignore_to_end_of_line();

    for (i = 1; i <= n; i++) {
        printf("%10d%10d\n", i, i * i);
        if (i % 24 == 0) {
            printf("Press Enter to continue...");
            ignore_to_end_of_line();
        }
    }

    return 0;
}
paddy
  • 60,864
  • 6
  • 61
  • 103
  • Nice. Micro [optimization](https://softwareengineering.stackexchange.com/q/80084/94903): `c != EOF && c != '\n'` --> `c != '\n' && c != EOF` as `'\n'` more likely. – chux - Reinstate Monica Aug 23 '22 at 13:05