3

I am trying to print a table of integer squares. The aim is to write a program that pauses after every 24 squares and asks the user to print Enter to continue. This is not too complex, I have "completed" the task at hand in C.

My concern: a seemingly insignificant (but observable) minor issue occurs when I compile & run the following code:

    #include <stdio.h>

    int main()
    {
      int i, n;

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

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

    }

My output is perfect, exactly what I want, EXCEPT for the first multiple of 24 (i.e. 24). For some reason if I select a large n, the table will print out perfectly but will only require me to press Enter from 48 onwards, the first printf output is weird and it doesn't require the user to press any key (let alone Enter). It looks like this:

            24       576
    Press Enter to coninue...        25       625
            26       676

but then the next time printf is utilised by the code all is seemingly perfect and I am required to press Enter to continue, as it ought to be.. (Sample of healthy output later on in the code and for all subsequent multiples of 24).

            48      2304
    Press Enter to coninue...
            49      2401

The one thing which rectifies this is if I put an extra getchar() function in between printf and while in the for loop. So the code is exactly the same except the for loop now looks like this:

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

In which case the code runs perfectly. Except that from from 48 onwards I am required to press Enter twice. Presumably this is because of the extra getchar() I have put in place but then why do I only need to press Enter once when i = 24?

My guess is that this has something to do with the (i - 1) % 24 argument but I can't see what the problem is. This is a question from Chapter 7 of KNK C Programming A Modern Approach. I am a self-taught programmer. I hope I have made my question easy to understand and that it elucidates something important about C. Could this be considered implementation-defined behaviour? Perhaps on another machine what I am describing would not have happened? And if not why not?

tommie997
  • 129
  • 6
  • 5
    `scanf()` (when you type `"48"`) leaves the enter in the input buffer. The 1st `getchar()` deals with that *pending* ``. Prefer using exclusively `fgets()` for **ALL** user input (including text files) – pmg Apr 05 '21 at 15:50
  • Does this answer your question? [scanf() leaves the new line char in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-new-line-char-in-the-buffer) – Brian61354270 Apr 05 '21 at 15:50
  • Why are you using `scanf` at all? Parameters like this should come from `argv` – William Pursell Apr 05 '21 at 15:52
  • I see, being told that scanf leaves the enter in the input buffer is a key. Further I'd just add that I haven't been using `fgets()`or `argv` because they haven't been mentioned yet in the book. Thank you for clearing this up. – tommie997 Apr 05 '21 at 16:15
  • @tommie997 `scanf()` does not leave the `'n'` due to the function, but due to the format `"%d"` which stops reading after the last numeric text character was found. Had you type `"48"`, would remain in `stdin`. – chux - Reinstate Monica Apr 05 '21 at 19:29

1 Answers1

1

After the call to scanf, there is a newline left in the input buffer. This newline gets picked up on the first call to getchar causing it to break out of the while loop.

You want to consume the newline after the scanf call by looping getchar until you get a newline.

scanf("%d", &n);
while (getchar() != '\n');
dbush
  • 205,898
  • 23
  • 218
  • 273
  • This makes sense. Could I not also just add a preliminary `getchar()` after `scanf` and before the for loop? – tommie997 Apr 05 '21 at 16:17
  • @tommie997 That's exactly what the code above does. – dbush Apr 05 '21 at 16:18
  • Rather doesn't it do a little more, as in it lets the user type anything until they press Enter. As opposed to just placing `getchar()` (without the while loop) which will only get rid of the one unnecessary newline character in the input buffer after scanf has been called? – tommie997 Apr 05 '21 at 16:20
  • @tommie997 yes, it will consume any extra characters the user entered after the number if there were any. – dbush Apr 05 '21 at 16:28
  • `while (getchar() != '\n');` in an infinite loop should `getchar()` return `EOF` due to a end-of-file. – chux - Reinstate Monica Apr 05 '21 at 19:26