5

I'm trying to make a simple command that pauses for user input. I think it'll be useful in Bash scripts.

Here's my code:

#include <stdio.h>
int main() {
  char key[1];
  puts("Press any key to continue...");
  fgets(key,1,stdin);
}

It doesn't even pause for user input.

I tried earlier to use getch() (ncurses). What happened is, the screen went blank and when I pressed a key, it went back to what was originally on the screen, and I saw:

$ ./pause
Press any key to continue...
$

It's somewhat what I wanted. But all I want is the equivalent of the pause command in DOS/Windows (I use Linux).

biggles5107
  • 287
  • 2
  • 4
  • 10

3 Answers3

15

From the GNU C Library Manual:

Function: char * fgets (char *s, int count, FILE *stream)

The fgets function reads characters from the stream stream up to and including a newline character and stores them in the string s, adding a null character to mark the end of the string. You must supply count characters worth of space in s, but the number of characters read is at most count − 1. The extra character space is used to hold the null character at the end of the string.

So, fgets(key,1,stdin); reads 0 characters and returns. (read: immediately)

Use getchar or getline instead.

Edit: fgets also doesn't return once count characters are available on the stream, it keeps waiting for a newline and then reads count characters, so "any key" might not be the correct wording in this case then.

You can use this example to avoid line-buffering:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch ( void ) 
{
  int ch;
  struct termios oldt, newt;
  
  tcgetattr ( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr ( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr ( STDIN_FILENO, TCSANOW, &oldt );
  
  return ch;
}

int main()
{
    printf("Press any key to continue.\n");
    mygetch();
    printf("Bye.\n");
}
Community
  • 1
  • 1
ccKep
  • 5,786
  • 19
  • 31
  • You can't as far as I know, stdin is line-buffered. – ccKep May 13 '12 at 22:02
  • Why it didn't wait for my input makes sense now. But I want something that waits for one key pressed, which is where ncurses comes in handy. – biggles5107 May 13 '12 at 22:08
  • 1
    Take a look at [Link](http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1042856625&id=1043284385), the code at the bottom worked fine for me. (Edited original answer with full code) – ccKep May 13 '12 at 22:13
2

I'm not sure how to add a comment under a post so this isn't really an answer but a comment,

In linux Stdin is buffered so you need to flush it which is what pressing 'enter' does on your terminal. It seems you want to read from an unbuffered stream i.e you want to react to a keypress imediately (without the need to explicitly flush it).

You can create your own unbuffered stream using a file discriptor and then read from it using "getc", you may have to use termios to setup unbuffered input as others have suggested.

Matt
  • 21
  • 1
1

This is a simple method that worked for me on Windows 10:

#include <stdlib.h>

void pause(void);

int main(void)
{
    printf("Testing pause.");
}

void pause(void)
{
    system("pause");
}
Jackal
  • 195
  • 9
  • The problem with this is that it merely runs the shell command 'pause,' which as I explained in OP, does not exist on Linux. I am trying to implement this myself. – biggles5107 Apr 07 '20 at 01:28