Solved

getch typeahead problem

Posted on 1998-07-22
18
501 Views
Last Modified: 2010-08-05
Whenever I use the getch() or getche() functions and follow with scanf or gets(), the character
typed by the user at the getch()/ getche() prompt is 'echoed' at the gets()/scanf prompt.  The only way to
avoid having the character picked up by these functions is to manually back over it.  It happens
with both getch and getche so I know its not the echo feature of the getche function.  I think it has
something to do with the fact that scanf/gets take arguments.  Any help appreciated.  Thanks.
0
Comment
Question by:dave140
  • 6
  • 4
  • 3
  • +3
18 Comments
 

Expert Comment

by:mallrat
ID: 1251783
Ok, haven't done much C coding in a while but I have a couple of Ideas.
I can remember this problem specifically with extended codes.

(I'M sure you know this but anyway)
Most keys on the keyboard will return 1 character.
However, there are many that will return 2 characters. "Extended Codes"
If i remember correctly, all the function keys and Alt? plus a key return extended codes.
Meaning simply that they put two characters in the input buffer.

The getch and getche functions just take the first character from the input buffer and leave the last one there. So if you use gets or Scanf or anything similar. That second character shows up on the console.

If this is your problem you solve it by doing the following.
The first character of an extended code is always the interger 0;
So if you use an interger variable to get the return of getch, you simply test if its equal to zero.
If it is then you know there is another character in the input buffer and you must get it out.
eg.
main()
{
       int ch;

       ch = getch();
       if(ch==0)
       {
           //Program will not pause here. It will just get the next character automatically            since it is an extended code;  
           ch=getch();
       }
       Or it could be that your just not flushing the input buffer enough(this would usually        cause weirder stuff.)
       Hope that was anywhere close to what you need.
0
 
LVL 11

Expert Comment

by:alexo
ID: 1251784
dave140, mallrat's answer, although technically correct, is not what you need.

Try the following:

        #include <stdio.h>
        #include <conio.h>
        void main()
        {
            int ch;
            char buff[256];
            ch = getch();
            fflush(stdin)
            gets(buff);
        }

0
 

Expert Comment

by:mallrat
ID: 1251785
Actually, to be more exact you should do this
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
main()
{
     int ch;
     char buff[256];
     //To get the character 'a'
     again: ch = getch();
     if( ch == 0)
     {
         ch = getch();
         fflush(stdin);    
         goto again;    
     }
     if(ch=='a')
     {
          fflush(stdin);
          gets(buff);
     }
     return 0;
}

 However, you should scrap the use of all the basic functios in the c headers that put input into a string because they can all be crashed rather convincingly.
You should wrute your own algorythm that gets your string input one character at a time.
 It is a good idea because it will get rid of your problem and most other related ones.
 Its not hard to build either but if you have problems just ask for an example here.
 Some of these people could whip it off in a matter of minutes.
By the way. What compiler are you using?
 
0
 

Author Comment

by:dave140
ID: 1251786
Mallrat/Alexo, thanks for the responses, but they don't seem to solve my problem.  First of all, I failed to mention that I am compiling these programs in Microsoft VC++ 5.0 as C programs on an Intel Pentium 200mhz MMX machine.  I typed, compiled, and ran your programs and the type-ahead problem was still there.  The buffer never seemed to have anything more in it than what the user enters at the getche 'prompt.'(I examined the contents of the variable used to hold what getch returned)  Mallrat, I like your idea about creating my own algorithm that inputs a string into an array one character at a time, but I believe I would continue have the same problem because there would still be a scanf or gets function following a getch or getche function.  I like the interactive nature of the getche function but it's starting to look as if it can cause more harm than good.
0
 

Author Comment

by:dave140
ID: 1251787
Mallrat/Alexo, thanks for the responses, but they don't seem to solve my problem.  First of all, I failed to mention that I am compiling these programs in Microsoft VC++ 5.0 as C programs on an Intel Pentium 200mhz MMX machine.  I typed, compiled, and ran your programs and the type-ahead problem was still there.  The buffer never seemed to have anything more in it than what the user enters at the getche 'prompt.'(I examined the contents of the variable used to hold what getch returned)  Mallrat, I like your idea about creating my own algorithm that inputs a string into an array one character at a time, but I believe I would continue have the same problem because there would still be a scanf or gets function following a getch or getche function.  I like the interactive nature of the getche function but it's starting to look as if it can cause more harm than good.
0
 

Author Comment

by:dave140
ID: 1251788
Mallrat/Alexo, thanks for the responses, but they don't seem to solve my problem.  First of all, I failed to mention that I am compiling these programs in Microsoft VC++ 5.0 as C programs on an Intel Pentium 200mhz MMX machine.  I typed, compiled, and ran your programs and the type-ahead problem was still there.  The buffer never seemed to have anything more in it than what the user enters at the getche 'prompt.'(I examined the contents of the variable used to hold what getch returned)  Mallrat, I like your idea about creating my own algorithm that inputs a string into an array one character at a time, but I believe I would continue have the same problem because there would still be a scanf or gets function following a getch or getche function.  I like the interactive nature of the getche function but it's starting to look as if it can cause more harm than good.
0
 

Expert Comment

by:mallrat
ID: 1251789
Dave140,
Post up your code where the problem exists, (the whole function)and let these guys have a look. Someone is sure to solve it for you my friend
0
 
LVL 11

Expert Comment

by:alexo
ID: 1251790
Dave140, What compiler?  What OS?
0
 
LVL 10

Expert Comment

by:rbr
ID: 1251791
I can offer you 2 things. First post your code and I will see what is wrong with it. Second if you are interested in generic input functions which work for DOS, Windows and Unix send an email to rbr@physik.kfunigraz.ac.at
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 11

Expert Comment

by:alexo
ID: 1251792
rbr, locking a question without providing an answer is not considered professional behavior.  The EE staff frown on it too.
0
 

Author Comment

by:dave140
ID: 1251793
Processor:  200 MHZ Intel Pentium MMX
OS: Windows 95
Compiler:  Microsoft Visual C++ 5.0

I am compiling this code as a C program:

#include "stdio.h"
#include "string.h"
#include "conio.h"

void main()
{
      char input, input2[20];

      input = getche();
      printf("\n");
      gets(input2);
}

If I run the program and type 'A' at the getche() function, 'A' appears on the new line before I type anything in response to the gets() function. Any insight appreciated.  

Thanks,

Dave140
0
 
LVL 11

Expert Comment

by:alexo
ID: 1251794
Huh?

I run your program (MSVC 4.2, NT)

First, I type 'a' and it gets echoed (getche() echoes the character, getch() does not).
Then, the cursor moves to a new line.
Then I type 'qwerty' which is also echoed.

Seems OK to me.  What's the problem?
0
 
LVL 1

Expert Comment

by:vladimir_12345
ID: 1251795
try this source:
================

#include "stdio.h"
#include "string.h"
#include "conio.h"

void main()
{
char input, input2[20];

input = getche();
fflush(stdout); // not stdin !!!
printf("\n");
gets(input2);
}

0
 

Author Comment

by:dave140
ID: 1251796
Vladimir, Mallrat, Alexo, RBR,

Still, no luck.  Do you think the problem is with something besides the code? I know there are other functions out there that can serve similar purposes, but why doesn't this one work as expected?

Windows 95, MSVC++ 5.0, 200MHZ Pentium MMX.
0
 

Author Comment

by:dave140
ID: 1251797
Vladimir, Mallrat, Alexo, RBR,

Still, no luck.  Do you think the problem is with something besides the code? I know there are other functions out there that can serve similar purposes, but why doesn't this one work as expected?

Windows 95, MSVC++ 5.0, 200MHZ Pentium MMX.
0
 
LVL 10

Expert Comment

by:rbr
ID: 1251798
I can offer you again, that I'll send you an generic input function, which is tested with many compilers and OSs. Send an email to rbr@physik.kfunigraz.ac.at
0
 
LVL 1

Expert Comment

by:vladimir_12345
ID: 1251799
Hi Dave140 !
It is very strange. I use Win95, MSVC++ 5.0, 200MHZ Pentium MMX
and the program works perfectly (even without fflush()).
I think that the problem is in another place. Do you check
you source within a large program or separately ?

0
 
LVL 2

Accepted Solution

by:
kellyjj earned 100 total points
ID: 1251800
Here are my rountines for Dos,  should work for you:

char *strinput(int x,int y,int max_len)
{
int cnt=0;
char *tmp="";
char *tmp2;
      do
      {
            if (kbhit())
            {
                  get_key();
                  poke_vid_mem(x,y,key_char);
                  cnt++;
                  x++;
                  *tmp2=key_char;
                  strcat(tmp,tmp2);
                  if (key_char==13) goto fin;
            }
      } while (cnt<max_len);
fin:
      return(tmp);
}



void get_key()
{
      asm
      {
            mov ax,0;
            mov ah,0x10;
            int 16h;
            mov key_char,al;
            mov extn_char,ah;
      }
}


void poke_vid_mem(unsigned int x_cor,unsigned int y_cor,unsigned char chr)
{
unsigned int off,col=0;

/*
      col=320;
      off=x_cor+(col*y_cor);
*/

/*
***************************************************************
as long as 0 is not passed should not cause a prob.
I use 160 here because there are 160 bytes in video memory for a 80x25 mode per
1 line. so x=1 and y=1 would be 160*0 +0
x=2 y=2  160*1 +2
even bytes are for the character, odd attribs
***************************************************************
*/
      col=160*(y_cor-1);
      x_cor=x_cor*2;
      if ( (x_cor % 2)!=0 ) x_cor--;
      off=x_cor+col;

      asm
      {
            push ds;
            push es;
            mov ax,VIDMEM;
            mov es,ax;
            mov di,off;
            mov ax,0;
            mov ah,chr;
            mov es:[di],ah;
            pop es;
            pop ds;
      }
}



Hope this helps

0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now