How to read data without the user pressing the enter key?

Discussion in 'C Programming' started by Rajen, Sep 9, 2006.

  1. Rajen

    Rajen Guest

    Suppose the field length is 25 characters.
    After entering the 25th character, it should be available to process.
    Program should not wait for the user to press enter/return key.

    Thank you.
     
    Rajen, Sep 9, 2006
    #1
    1. Advertisements

  2. There is no way to do this in standard C. A number of systems offer
    extensions that you could use, but those are platform specific, or
    part of a standard such as POSIX if you are fortunate. You need to
    ask on a newsgroup for your platform to find out what is available
    to you.


    Please note that the situation is much trickier than you have
    expressed. Suppose the user makes a mistake: how are they going to
    correct the mistake, considering that backspace or del are "characters"
    and considering that you haven't gotten into display controls such as
    mechanisms for adding or removing characters at particular positions on
    the -display-. (Sending backspace space backspace is *not* certain to
    leave a blank at that location.) Now suppose further that they made the
    mistake just as they entered the 25th character?

    Have you planned as far ahead as "forms" and some mechanism for
    returning back to a previous form entry panel for corrections if you
    automatically advanced when the user was not ready to do so?

    You can see how much complication and how many platform dependancies you
    bring in just to save the user one keystroke per field!
     
    Walter Roberson, Sep 9, 2006
    #2
    1. Advertisements

  3. Rajen

    Ben Pfaff Guest

    This is in the FAQ.

    19.1: How can I read a single character from the keyboard without
    waiting for the RETURN key? How can I stop characters from
    being echoed on the screen as they're typed?

    A: Alas, there is no standard or portable way to do these things in
    C. Concepts such as screens and keyboards are not even
    mentioned in the Standard, which deals only with simple I/O
    "streams" of characters.

    At some level, interactive keyboard input is usually collected
    and presented to the requesting program a line at a time. This
    gives the operating system a chance to support input line
    editing (backspace/delete/rubout, etc.) in a consistent way,
    without requiring that it be built into every program. Only
    when the user is satisfied and presses the RETURN key (or
    equivalent) is the line made available to the calling program.
    Even if the calling program appears to be reading input a
    character at a time (with getchar() or the like), the first call
    blocks until the user has typed an entire line, at which point
    potentially many characters become available and many character
    requests (e.g. getchar() calls) are satisfied in quick
    succession.

    When a program wants to read each character immediately as it
    arrives, its course of action will depend on where in the input
    stream the line collection is happening and how it can be
    disabled. Under some systems (e.g. MS-DOS, VMS in some modes),
    a program can use a different or modified set of OS-level input
    calls to bypass line-at-a-time input processing. Under other
    systems (e.g. Unix, VMS in other modes), the part of the
    operating system responsible for serial input (often called the
    "terminal driver") must be placed in a mode which turns off line-
    at-a-time processing, after which all calls to the usual input
    routines (e.g. read(), getchar(), etc.) will return characters
    immediately. Finally, a few systems (particularly older, batch-
    oriented mainframes) perform input processing in peripheral
    processors which cannot be told to do anything other than line-
    at-a-time input.

    Therefore, when you need to do character-at-a-time input (or
    disable keyboard echo, which is an analogous problem), you will
    have to use a technique specific to the system you're using,
    assuming it provides one. Since comp.lang.c is oriented towards
    those topics that the C language has defined support for, you
    will usually get better answers to other questions by referring
    to a system-specific newsgroup such as comp.unix.questions or
    comp.os.msdos.programmer, and to the FAQ lists for these groups.
    Note that the answers are often not unique even across different
    variants of a system; bear in mind when answering system-
    specific questions that the answer that applies to your system
    may not apply to everyone else's.

    However, since these questions are frequently asked here, here
    are brief answers for some common situations.

    Some versions of curses have functions called cbreak(),
    noecho(), and getch() which do what you want. If you're
    specifically trying to read a short password without echo, you
    might try getpass(). Under Unix, you can use ioctl() to play
    with the terminal driver modes (CBREAK or RAW under "classic"
    versions; ICANON, c_cc[VMIN] and c_cc[VTIME] under System V or
    POSIX systems; ECHO under all versions), or in a pinch, system()
    and the stty command. (For more information, see <sgtty.h> and
    tty(4) under classic versions, <termio.h> and termio(4) under
    System V, or <termios.h> and termios(4) under POSIX.) Under
    MS-DOS, use getch() or getche(), or the corresponding BIOS
    interrupts. Under VMS, try the Screen Management (SMG$)
    routines, or curses, or issue low-level $QIO's with the
    IO$_READVBLK function code (and perhaps IO$M_NOECHO, and others)
    to ask for one character at a time. (It's also possible to set
    character-at-a-time or "pass through" modes in the VMS terminal
    driver.) Under other operating systems, you're on your own.

    (As an aside, note that simply using setbuf() or setvbuf() to
    set stdin to unbuffered will *not* generally serve to allow
    character-at-a-time input.)

    If you're trying to write a portable program, a good approach is
    to define your own suite of three functions to (1) set the
    terminal driver or input system into character-at-a-time mode
    (if necessary), (2) get characters, and (3) return the terminal
    driver to its initial state when the program is finished.
    (Ideally, such a set of functions might be part of the C
    Standard, some day.) The extended versions of this FAQ list
    (see question 20.40) contain examples of such functions for
    several popular systems.

    See also question 19.2.

    References: PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1; POSIX
    Sec. 7.

    19.2: How can I find out if there are characters available for reading
    (and if so, how many)? Alternatively, how can I do a read that
    will not block if there are no characters available?

    A: These, too, are entirely operating-system-specific. Some
    versions of curses have a nodelay() function. Depending on your
    system, you may also be able to use "nonblocking I/O", or a
    system call named "select" or "poll", or the FIONREAD ioctl, or
    c_cc[VTIME], or kbhit(), or rdchk(), or the O_NDELAY option to
    open() or fcntl(). See also question 19.1.
     
    Ben Pfaff, Sep 9, 2006
    #3
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.