Unbuffered I/O in ANSI C
Asked Answered
L

3

8

For the sake of education, and programming practice, I'd like to write a simple library that can handle raw keyboard input, and output to the terminal in 'real time'.

I'd like to stick with ansi C as much as possible, I just have no idea where to start something like this. I've done several google searches, and 99% of the results use libraries, or are for C++.

I'd really like to get it working in windows, then port it to OSX when I have the time.

Leasehold answered 30/10, 2009 at 3:50 Comment(0)
M
5

Sticking with Standard C as much as possible is a good idea, but you are not going to get very far with your adopted task using just Standard C. The mechanisms to obtain characters from the terminal one at a time are inherently platform specific. For POSIX systems (MacOS X), look at the <termios.h> header. Older systems use a vast variety of headers and system calls to achieve similar effects. You'll have to decide whether you are going to do any special character handling, remembering that things like 'line kill' can appear at the end of the line and zap all the characters entered so far.

For Windows, you'll need to delve into the WIN32 API - there is going to be essentially no commonality in the code between Unix and Windows, at least where you put the 'terminal' into character-by-character mode. Once you've got a mechanism to read single characters, you can manage common code - probably.

Also, you'll need to worry about the differences between characters and the keys pressed. For example, to enter 'ï' on MacOS X, you type option-u and i. That's three key presses.

Motmot answered 30/10, 2009 at 4:17 Comment(1)
I was afraid that's what I'd have to do... I guess I'll get on it... is the win32API in windows.h? Thanks for the direction.. :)Leasehold
O
5

To set an open stream to be non-buffered using ANSI C, you can do this:

#include <stdio.h>
if (setvbuf(fd, NULL, _IONBF, 0) == 0)
  printf("Set stream to unbuffered mode\n");

(Reference: C89 4.9.5.6)

However, after that you're on your own. :-)

Orange answered 30/10, 2009 at 4:46 Comment(2)
The first argument of setvbuf() is a C file handle, not a file descriptor.Depressant
I used this example and it work to ensure that the C library does not read more than is necessary from the stream, leaving the rest of the stream intact for subsequent processes in the pipe.Kemerovo
M
2

This is not possible using only standard ISO C. However, you can try using the following:

#include <stdio.h>
void setbuf(FILE * restrict stream, char * restrict buf); 

and related functions.

Your best bet though is to use the ncurses library.

Moneyed answered 30/10, 2009 at 4:5 Comment(1)
There is also a decent open source curses for windows out there; google "pdcurses". In that way it's perfectly possible to code against curses and end up with something at works on all the platforms the questioner asks for -- I've done it.Unalloyed

© 2022 - 2024 — McMap. All rights reserved.