Link to home
Start Free TrialLog in
Avatar of Intern
Intern

asked on

Input without Enter key

I am trying to let a user exit out of a current menu by pressing one key, but also let them enter a string of characters if they want to continue.  I am using getch() or getche() to get the first character and then ungetch() if the character was not the one that I wanted, then I read the whole string in.

The following code works if I put it at the beginning of the program, but fails if I put it later on.  And by "Fails" I mean that the user can only input 1 character and the program continues on, it will not wait for enter.  But the code works at the begining of the program?????  I am so confused.

// declarations elswhere are :
// char choice;
// string input_buffer;
// CString cBusiness_Unit;

      cout<<"Please scan the "<<endl;
      cout<<"Business Unit: ";

      choice = getche();
      if(toupper(choice) == 90)//check for 'Z' (escape from menu)
      {
            exit_ItemID = 1;
            exit_program = 1;
      }
      ungetc(choice, stdin);
      cin>>input_buffer;
      cBusiness_Unit = input_buffer.c_str();
      cBusiness_Unit.MakeUpper();

Any Ideas?
Avatar of Intern
Intern

ASKER

I also tried it like this and the same thing happened:

cin>>cBusiness_Unit.GetBuffer(100); //Get Business Unit from input buffer
cBusiness_Unit.ReleaseBuffer ();
cBusiness_Unit.MakeUpper();
Avatar of jkr
As you are using Windows, I'd rather try sth. like


    cout<<"Please scan the "<<endl;
    cout<<"Business Unit: ";

    INPUT_RECORD ir;    
    DWORD dwRead;
    PeekConsoleInput ( GetStdHandle (STD_INPUT_HANDLE), &ir, 1, &dwRead);

    if ( KEY_EVENT == ir.EventType) {
 
      choice = ir.KeyEvent.uChar;
    }
    if(toupper(choice) == 90)//check for 'Z' (escape from menu)
    {
         exit_ItemID = 1;
         exit_program = 1;
    }
    ungetc(choice, stdin);
    cin>>input_buffer;
    cBusiness_Unit = input_buffer.c_str();
    cBusiness_Unit.MakeUpper();


Avatar of Intern

ASKER

I tried this, and I get an error.  By the way I changed "ir.KeyEvent.uChar" to "ir.Event.KeyEvent.uChar"

      INPUT_RECORD ir;    
   DWORD dwRead;
   PeekConsoleInput ( GetStdHandle (STD_INPUT_HANDLE), &ir, 1, &dwRead);

   if ( KEY_EVENT == ir.EventType) {

      choice = ir.Event.KeyEvent.uChar;  //error here
   }

error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'union ' (or there is no acceptable conversion)
Ooops, I am sorry - just typed it into the browser window. It should read

  if ( KEY_EVENT == ir.EventType) {

     choice = ir.Event.KeyEvent.uChar.AsciiChar;
  }
Avatar of Intern

ASKER

Now it will not even take one character and put it in Business_Unit, it just contiues on with the program.

code:
      INPUT_RECORD ir;    
   DWORD dwRead;
   PeekConsoleInput ( GetStdHandle (STD_INPUT_HANDLE), &ir, 1, &dwRead);

   if ( KEY_EVENT == ir.EventType) {

      choice = ir.Event.KeyEvent.uChar.AsciiChar;
   }

      if(toupper(choice) == 90)//check for escape
      {
            exit_ItemID = 1;
            exit_program = 1;
      }
      ungetc(choice, stdin);
      cin>>input_buffer;
      cBusiness_Unit = input_buffer.c_str();
      cBusiness_Unit.MakeUpper();

//Only input before this point is:

      system("cls");
      cout<<"    Transfer 2.0 "<<endl;
      cout<<"---------------------";
      cout<<endl<<"Enter User ID: ";
      cin>>cUser_ID.GetBuffer(100); //Get user ID from input buffer
      cUser_ID.ReleaseBuffer ();
You should remove the "ungetc()" line also... This was the main idea to post the above approach, as mixing C and C++ streams will cause confusion.
Avatar of Intern

ASKER

sorry... missed that

But it still does not work.  It will excecute the new cout statement I put in before I enter any character at all.

      INPUT_RECORD ir;    
   DWORD dwRead;
   PeekConsoleInput ( GetStdHandle (STD_INPUT_HANDLE), &ir, 1, &dwRead);

   if ( KEY_EVENT == ir.EventType) {

      choice = ir.Event.KeyEvent.uChar.AsciiChar;
   }
      cout<<"choice = "<<choice<<endl;

      if(toupper(choice) == 90)//check for escape
      {
            exit_ItemID = 1;
            exit_program = 1;
      }
      //ungetc(choice, stdin);
      cin>>input_buffer;
      cBusiness_Unit = input_buffer.c_str();
      cBusiness_Unit.MakeUpper();
Hmm... have you thought of

char choice;

    cin >> choice;

    if(toupper(choice) == 90)//check for escape
    {
         exit_ItemID = 1;
         exit_program = 1;
    }

    cin>>input_buffer;
    cBusiness_Unit = CString ( choice) + input_buffer.c_str();
    cBusiness_Unit.MakeUpper();
Avatar of Intern

ASKER

That would work to check the first character but the cin statement still waits until the user presses the enter key, and that is the main thing I need to get rid of.
Avatar of Intern

ASKER

I have gotten it to sort of work using getch() but the problem is that the user can not erase the first character entered.  And that is not acceptable either.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Intern

ASKER

what is this line supposed to be:

acInBuf=(char *)malloc(nInputMax+2)))

acInBuf is not declared and I don't know what type it should be, plus extra )'s
Ooops, sorry, just make it read

char* acInBuf;

acInBuf=(char *)malloc(nInputMax+2));


Avatar of Intern

ASKER

I changed one thing :

#define CR 10

the '\r' wasn't working, but anyway the problem is still that you have to press enter after pressing 'Z'
Hmm, you shouldn't - the statement

                if ( cEscape == (char) nInput) {

                  free ( acInBuf);
                   return false;
               }

should take care of it...
Avatar of Intern

ASKER

I put a cout statement in like the following and the only time I saw it was after I pressed 'Enter' :

while(CR!=(nInput=fgetc(stdin)))
{
     cout<<"Test Statement"<<endl;

It is not leaving fgetc(stdin) until you press enter.
fflush(stdin);  ?

try flushing the input stream and then call your beginning code again.  See if that works, or will it wait for an enter.

#include<iostream.h>


int main()
{
char string[30];
string[0]=getch();
cin>>&string[1];
cout<<string;
}

check if this logic works for u.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Intern

ASKER

shajithchandran

Yours almost does what I want it to, Exept I can not erase the first character if I started to input it wrong (eg.  typed : 1234, actually wanted 9234, I can not backspace over the 1 to change it)  
Avatar of Intern

ASKER

I built something that works, at least on my desktop.  I don't know if it will work through a telnet session on a handheld scanner (purpose of program) but I will find out soon enough.  Here is my solution:

char string[30];
int i = 0;
char ch = getche();
while(ch != 10 && ch != 13)
{
      if(ch == '\b')
      {
            cout<<' '<<'\b';
            i--;
      }
      else
      {
            string[i] = ch;
            i++;
      }
      ch = getche();
}
string[i] = '\0';
cout<<"\nThe whole string is"<<string;
Avatar of Intern

ASKER

QUESTION:

can I convert string[30] to a CString??
Avatar of Intern

ASKER

>>can I convert string[30] to a CString??

lol, nevermind


I will give some points to both shajithchandran and jkr for all of your help.  Thank You
Thank you!