DOS/Windows-specific
C/C++ Function Reference
Files
DOS/Windows distinguishes between text and non-text files. If you open a file
(using fopen, open, or _open) without special precautions
it will be assumed to be a text file, regardless of its name or contents. Text files
are processed strangely. Attempting to print \n, \r, or the sequence \r\n
always results in the sequence \r\n being actually printed. This ruins binary
data. On reading, \r is similarly mutilated, the byte 0xFF can
appear to be the end of the file, and who knows what other nonsense occurs.
All of this can be avoided. If you are opening a file that should not be treated
as text: a file that contains binary or unformatted data, indicate that fact
when opening the file. Use one of the following:
FILE * f = fopen("name.dat", "rb");
FILE * f = fopen("name.dat", "wb");
int f = open("name.dat", O_RDONLY | O_BINARY);
All the normal forms of open and fopen are available. Adding the
letter "b" or the flag O_BINARY to the normal modes is all that
is required to disable disastrous character processing.
Keyboard and Screen
The following appies only to "Console Applications", as visula C/C++ calls them.
If you create a plain "Application", you will have to program all input and output
through event loops and windows components. The following functions interact
through a little black "DOS shell window".
Output to the screen is not fully buffered. Under normal unix programming, to produce
a "progress bar" that makes a slow trail of dots across the screen, it is necessary
to use something like this: printf("."); fflush(stdout);, otherwise nothing
is printed until a whole line of dots has been produced. Under windows the dots will
appear immediately, the fflsuh is not needed. (Under unix, if lower level i/o is
performed, the buffering can also be avoided: write(1, ".", 1); also has
an immediate effect).
int _kbhit(void)
include: <conio.h>
Returns 1 if a keyboard key has been hit and is ready to read, 0 otherwise.
This is not a fast function. See the sample following _getch().
Note that there is an underline character in the name.
int _getch(void)
include: <conio.h>
Waits until a keyboard key has been typed, then returns the code (usually
ASCII code) associated with it. The function only waits for a single keypress,
it does not wait until ENTER has been pressed. When used in conjunction with
_kbhit(), all waiting can be prevented, even if no keys have been pressed.
The character typed is not echoed.
Sample
This loop repeats everything that is typed, as soon as it is typed, except
that capitals are replaced with lower-case and vice versa. It also prints a
"." every time a second passes without any keys being typed.
The timing is of course approximate, and on faster computers the dots
will come out faster. But note how small the variable cnt is when a second
has elapsed. _kbhit() is not a fast function. 270,000 calls per second
on an AMDS Athlon Xp 2000+ processor.
A more CPU-efficient version is shown after the description of the Sleep
function.
int cnt=0;
while (1)
{ if (_kbhit())
{ cnt=0;
int x=_getch();
if (x>='a' && x<='z') x-=32;
else if (x>='A' && x<='Z') x+=32;
printf("[%c]", x); }
else
{ cnt+=1;
if (cnt>=270000)
{ printf(".");
cnt=0; } } } }
int _getche(void)
include: <conio.h>
Exactly the same as _getch(), except that they keystroke is automatically
echoed as is normal for interacting input.
Delay/Sleep
The unix functions sleep and usleep are not available in their
simple form. The windows function Sleep() may be used (note the capital S)
but it introduces complexities. It requires two heavyweight include files that
define a lot of global names, and the chances for a name clash are high. Unfortunately
I do not know of any other way of making a pause in processing without using a
tight loop that keeps the CPU fully occupied.
void Sleep(int ms)
include: <windows.h>
include: <winbase.h>
The parameter is the number of milliseconds to sleep, and is actually
declared as a DWORD, but that is functionally equivalent to int.
This function actually causes the calling Thread to sleep for the
specififed time, not the whole process. The sleep time is fairly accurate, and
is not affected by differences in CPU speed.
The following is the example that was provided for _getch() and _kbhit(), but
in a more friednly and efficient form:
while (1)
{ if (_kbhit())
{ int x=_getch();
if (x>='a' && x<='z') x-=32;
else if (x>='A' && x<='Z') x+=32;
printf("[%c]", x); }
else
{ Sleep(1000);
printf("."); } }