3

I'm trying to make a program that asks the user to write 4 numbers, and after these 4 numbers, the program will take those numbers without having the user to press Enter. I have tried to use the scanf() function, but scanf() requires the user to press Enter. Does someone know how can I do this?

kontulai
  • 876
  • 5
  • 19
  • 1
    Possible duplicate of [Scanning multiple numbers without scanning enter in C](http://stackoverflow.com/questions/34570630/scanning-multiple-numbers-without-scanning-enter-in-c) – javaDeveloper Dec 28 '16 at 09:40
  • 1
    Possible duplicate of [Making stdin non-blocking](http://stackoverflow.com/questions/8101079/making-stdin-non-blocking) – Stargateur Dec 28 '16 at 09:45
  • It is possible, If you use array for storing your input numbers after then retrieve the number from this array one by one. But it will take single digit. It is very tough to understand your situation, So highlight your question with example. – Kabir Hossain Dec 28 '16 at 09:48
  • So when should your program start taking input? When the user has typed the last digit of the last number? How should your program know which digit is the last one? What if the user has spotted a mistake in the last digit and wants to correct it? – n. m. could be an AI Dec 28 '16 at 12:04

3 Answers3

3

In UNIX, to control when data is returned from a terminal device you use tcsetattr()/tcgetattr() functions to change the characteristics of the terminal device. Apparently these functions are POSIX.2001 too.

Here is a simple C program that will do what you want, by setting the terminal device to return characters to the reader one character at a time (see inline comments, robust error checking not included):

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

int main(int argc, char * argv[]) {
  int i[4] = {0};
  struct termios oldtermios, newtermios;
  tcgetattr(STDIN_FILENO, &oldtermios);
  newtermios = oldtermios;
  newtermios.c_lflag &= ~ICANON; // Turn off canonical mode.
  // Wait for 1 character only.
  newtermios.c_cc[VMIN] = 1;
  tcsetattr(STDIN_FILENO, TCSANOW,  &newtermios);
  do {
    printf("Enter four numbers:\n");
    int ns = scanf(" %d %d %d %d", &i[0], &i[1], &i[2], &i[3]);
    if(ns == EOF) {
      perror("Scan failed. Exiting");
      break;
    }
    else if(ns != 4) {
      printf("\nScan failed. Only read %d numbers. Press enter to continue.\n", ns);
      while((i[0] = getchar()) != '\n' && i[0] != EOF);
    }
    else {
      printf("\nScanned %d numbers %d %d %d %d\n", ns, i[0], i[1], i[2], i[3]);
    }
  } while(1);
  return 1;
}
spinkus
  • 7,694
  • 4
  • 38
  • 62
  • @Stargateur it's a cut back example. In many scenarios you would want to reuse that, so the example shows common practice for doing so. – spinkus Dec 28 '16 at 10:08
  • 1
    @Stargateur, I'm not going to add error checking. If I add it to scanf() what about all the other system calls. If I were to do "full" error checking I'd include error checking macros which would confound the essence of the answer further. – spinkus Dec 28 '16 at 10:15
  • 2
    @Stargateur Down voting because no error checking? Jeez. – spinkus Dec 28 '16 at 10:19
  • 1
    @Stargateur It doesn't return every second. **scanf() blocks**. But your right in that to wake every second is redundant in this case. Removed that line. – spinkus Dec 28 '16 at 10:41
  • Well, just `if (scanf(...) == 4) printf(...)` would be enough... It was just to show that scanf **need** to be check. Input need to be check it's very important to understand for beginner. – Stargateur Dec 28 '16 at 11:47
0

You can use getch() function. It getting one character and not required press Enter.

Edward
  • 149
  • 7
0

The issue here is not with scanf or even with C standard. Your terminal is not sending data to your input buffer before you press enter.

Solutions will vary based on platform you are using. My favorite solution in this case is to use curses library. It exists on all posix platforms and is ported to windows as pdcurses (and maybe others).

Sample code and a really good tutorial can be found here: http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/init.html#ABOUTINIT

vguberinic
  • 315
  • 1
  • 6