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

Recommended Answers

All 3 Replies

>>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.

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;
}

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;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.