0

hey, been working on a program and I had a need for a password line (btw I am using linux w/ gcc compiler). while I was making it I checked the net and found there's no getch() for linux, so I frankensteined one from several sources and got it to work. Only problem is, it doesn't register backspace ('\b'), so people can't correct mistakes. I tried using a different key instead of backspace, like \t for example, it worked as it should, getchar() registered it, it just doesn't seem to like \b. here's the code:

#include <cstring>
#include <iostream>
#include <unistd.h>
using namespace std;

#ifndef KBHITh
#define KBHITh

#include <termios.h>

class keyboard
{
public:

	keyboard();
	~keyboard();

private:

	struct termios initial_settings, new_settings;
};

#endif 

keyboard::keyboard()
{
	tcgetattr(0,&initial_settings);
	new_settings = initial_settings;
	new_settings.c_lflag &= ~ICANON;
	new_settings.c_lflag &= ~ECHO;
	new_settings.c_lflag &= ~ISIG;
	new_settings.c_cc[VMIN] = 1;
	new_settings.c_cc[VTIME] = 0;
	tcsetattr(0, TCSANOW, &new_settings);
}

keyboard::~keyboard()
{
	tcsetattr(0, TCSANOW, &initial_settings);
}

int main()
{
	keyboard my_board; //essentially removes line buffer
	string pass="";
	char c=' ';
	cout << "Testing passwords, enter a string to passwordize\n";
	
	while(c != '\n')
	{
		c = getchar();
		if(c != '\n')
		{
			if(c == '\b') //doesn't like this line
			{
				pass=pass.substr(0,pass.size()-1);
				cout << "\010 \010" << flush;
			}
			else
			{
				pass.push_back(c);
				cout << "*" << flush;
			}
		}
	}

        my_board.~keyboard(); //reverts to normal line buffering
	cout << "\nYou entered: \"" << pass << "\"" << endl;
		
	return 0;
}

I've heard rumors of getchar not being able to read backspaces, but I wasn't sure. Also, I have no doubt there are better ways to emulate getch(), if you know of one please point me in the right direction. Any help would be appreciated.

~J

2
Contributors
3
Replies
7
Views
8 Years
Discussion Span
Last Post by jesseb07
0

>>Also, I have no doubt there are better ways to emulate getch(), if you know of one please point me in the right direction.

Its called curses.

0

hmmm... yes that does the job (and may look a little neater), but it clears the screen and only outputs things from the function until the program ends, that is not something I want to happen when I actually implement the function in the real program, unless there is an option for it not to do that. It also seems to again not register '\b', so I still have my original problem. code follows.

#include <cstring>
#include <iostream>
#include <ncurses.h>
using namespace std;

int main()
{
	initscr();
	noecho();
	string pass="";
	char c=' ';
	cout << "Testing password stuff, enter a string to passwordize1\n" << flush;
	
	while(c != '\n')
	{
		c = getch();
		if(c != '\n')
		{
			if(c == '\b')
			{
				pass=pass.substr(0,pass.size()-1);
				cout << "\010 \010" << flush;
			}
			else
			{
				pass.push_back(c);
				cout << "*" << flush;
			}
		}
	}

	endwin();
	cout << "\nYou entered: \"" << pass << "\"" << endl;
		
	return 0;
}
0

I got it to read backspaces, keypad() does that trick. I still wish there was another way to do it while still inside the terminal. That just confirms the things I heard that the terminal intercepts the backspace before it can get to the program (not sure why, but it seems that way). Anywho, thanks for the nudge Ancient Dragon, I think I can still make it look/do the things I would like. For sake of completeness on anyone following this thread, here's the finished code:

#include <cstring>
#include <iostream>
#include <ncurses.h>
using namespace std;

int main()
{
	initscr();
	noecho();
	keypad(stdscr, TRUE);
	string pass="";
	int c=0;
	cout << "Testing password stuff, enter a string to passwordize1\n" << flush;
	
	while(c != '\n')
	{
		c = getch();
		if(c != '\n')
		{
			if(c == KEY_BACKSPACE)
			{
				pass=pass.substr(0,pass.size()-1);
				cout << "\010 \010" << flush;
			}
			else
			{
				pass.push_back(c);
				cout << "*" << flush;
			}
		}
	}

	endwin();
	cout << "\nYou entered: \"" << pass << "\"" << endl;
		
	return 0;
}
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.