0

I have a program that scans on user input with i=getchar(); and it works. To prevent that the user has to press Enter every time i used that:

    tcgetattr(STDIN_FILENO,&old_tio);
    new_tio=old_tio;
    new_tio.c_lflag &=(~ICANON & ~ECHO);
    tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);

And i reset with:

    tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);

After that the user has to type something. I used this for it:

string userinput;
cin >> userinput;

But the console doesn't show the typed text (while typing). I tried to reenable local echo manually with this:

tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
old_tio.c_lflag |= ECHO;

But the console still doesn't show the local echo It's 10pm and i'm very sleepy so my question may be very easy to answer

Leonard Schütz
  • 517
  • 1
  • 7
  • 16
  • 1
    are you sure your last two lines aren't the wrong order? – woolstar Nov 27 '13 at 21:37
  • strange. The old_io really should contain the echo flag, so your first resetting attempt should be perfectly fine. Have you tried checking what flags are being stored in new_ and old_ variables? – quetzalcoatl Nov 27 '13 at 21:44
  • @woolstar thanks! They were in the wrong order.. How did i oversee that.. Please write an answer so i can upvote and everyone can benefit from it. Most people don't read the comments – Leonard Schütz Nov 28 '13 at 01:12

2 Answers2

0

The code works for me (see below). It may be worth verifying that all system calls are actually successful. Also, you didn't show the entire code: I could imagine that the switch to the restored input mode hadn't been done. Since I can't reproduce the problem, I can't comment on why it doesn't work.

Here is the code I used for testing:

#include <termios.h>
#include <iostream>
#include <string>

int main()
{
    termios old_tio, new_tio;
    int rc = tcgetattr(0,&old_tio);
    std::cout << "rc1=" << rc << '\n';
    new_tio=old_tio;
    new_tio.c_lflag &=(~ICANON & ~ECHO);
    rc = tcsetattr(0,TCSANOW,&new_tio);
    std::cout << "rc2=" << rc << '\n';

    std::string value;
    if (std::cin >> value) {
        std::cout << "value='" << value << "'\n";
    }

    rc = tcsetattr(0,TCSANOW,&old_tio);
    std::cout << "rc3=" << rc << '\n' << std::flush;

    if (std::cin >> value) {
        std::cout << "value='" << value << "'\n";
    }
}
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

Your call to set was called before you changed the attribute:

tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
old_tio.c_lflag |= ECHO;

Switch the order and it should work.

woolstar
  • 5,063
  • 20
  • 31