Mail Archives: djgpp/1996/04/29/01:59:08
On Sat, 27 Apr 1996, Y. Lazarovitch wrote:
> I had a program that sits in a loop and gets and prints input using the
> cgets/cprintf functions. When I would hit an arrow key, it would seem as
> if cgets stops taking input, and after a few seconds I would get a
> "general protection" error and the program would crash. This small
> program, although it doesn't cause a GPF (it was probably some other
> part of my program that caused it) does show that cgets(), once it gets
> an arrow key, continues "getting" some kind of input, and stops when it
> reaches the maximum characters specified, and when cgets() is called
> again, it still gets the same garbage, and so on.
Your loop isn't defensive enough about values that `cgets' returns: you
don't test whether it read any input at all. If `cgets' didn't read
anything, it's wrong to test the first character for a certain value.
Thus the following loop
> while(input[2] != '0') { /* first char input is in third element */
> cgets(input);
> cprintf("\r\nYou entered: %s\r\n", input + 2);
> }
should have been written, e.g., like this:
while (input[1] > 0 && input[2] != '0') {
cgets (input);
cprintf ("\r\nYou entered: %s\r\n", input + 2);
}
As it happens, `cgets' stops reading and returns when it sees any special
character (that doesn't have an ASCII code), like an arrow key--but it
calls `ungetch' to push that key back so it would be returned by the next
call by any of the conio functions that return keystrokes. The next time
`cgets' is called, it sees the same arrow character, pushes it back and
returns with an empty string, but your program never checks this. So you
enter an endless loop whereby the same arrow key is seen by `cgets' time
and again.
Btw, I'd advise against using cgets. IMHO, it assumes too much about
what the application wants (e.g., how does it know I don't want to see
any special characters?). It is a compatibility function devised after
its Borland namesake, and is only good for reading strings from
text-oriented forms, or some such. It's much better to call the
functions that get you *any* character (like `getxkey') and build your
own mechanism that assembles keystrokes into strings.
- Raw text -