Handling password input securely, where characters are not displayed as they're typed, is an important feature for manyΒ applications.
In C++, this isn't as straightforward as in some other languages, but we can achieve it using platform-specific functions. Let's explore how to do this on both Windows and Unix-like systems (Linux,Β macOS).
For Windows, we'll use the _getch()
function from <conio.h>
:
#include <iostream>
#include <string>
#include <conio.h> // Windows-specific header
std::string getPassword(){
std::string password;
char ch;
// Read until Enter is pressed
while ((ch = _getch()) != '\r') {
// Handle backspace
if (ch == '\b') {
if (!password.empty()) {
std::cout << "\b \b";
password.pop_back();
}
} else {
password += ch;
std::cout << '*';
}
}
std::cout << '\n';
return password;
}
int main(){
std::cout << "Enter password: ";
std::string password = getPassword();
std::cout << "Password entered: " << password;
}
This Windows implementation uses _getch()
to read characters without echoing them to the console. We print an asterisk for each character entered to provide visualΒ feedback.
Enter password: ******
Password entered: secret
For Unix-like systems, we'll use the termios.h
header to modify terminalΒ attributes:
#include <iostream>
#include <string>
#include <termios.h>
#include <unistd.h>
std::string getPassword(){
std::string password;
termios oldt;
tcgetattr(STDIN_FILENO, &oldt);
termios newt = oldt;
newt.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
char ch;
while ((ch = getchar()) != '\n') {
if (ch == 127) {
// Handle backspace
if (!password.empty()) {
std::cout << "\b \b";
password.pop_back();
}
} else {
password += ch;
std::cout << '*';
}
}
std::cout << '\n';
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return password;
}
int main(){
std::cout << "Enter password: ";
std::string password = getPassword();
std::cout << "Password entered: " << password;
}
Enter password: ******
Password entered: secret
In this Unix-like system implementation, we temporarily disable echo in the terminal, read characters one by one, and restore the original terminal settingsΒ afterwards.
To create a cross-platform solution, you can use conditionalΒ compilation:
#include <iostream>
#include <string>
#ifdef _WIN32
#include <conio.h>
#else
#include <termios.h>
#include <unistd.h>
#endif
std::string getPassword(){
std::string password;
#ifdef _WIN32
// Windows implementation
char ch;
while ((ch = _getch()) != '\r') {
if (ch == '\b') {
if (!password.empty()) {
std::cout << "\b \b";
password.pop_back();
}
} else {
password += ch;
std::cout << '*';
}
}
#else
// Unix-like implementation
termios oldt;
tcgetattr(STDIN_FILENO, &oldt);
termios newt = oldt;
newt.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
char ch;
while ((ch = getchar()) != '\n') {
if (ch == 127) {
if (!password.empty()) {
std::cout << "\b \b";
password.pop_back();
}
} else {
password += ch;
std::cout << '*';
}
}
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#endif
std::cout << '\n';
return password;
}
int main(){
std::cout << "Enter password: ";
std::string password = getPassword();
std::cout << "Password entered: " << password;
}
Enter password: ******
Password entered: secret
This cross-platform solution uses conditional compilation to choose the appropriate implementation based on the targetΒ platform.
Remember, while these methods hide password input from the screen, they don't provide complete security. For production systems, consider using secure password hashing algorithms and avoid storing plaintextΒ passwords.
Answers to questions are automatically generated and may not have been reviewed.
This lesson introduces the fundamentals of capturing user input, using std::cin
and std::getline