User Input in the Terminal

Secure Password Input in C++

How do I handle password input where characters should not be displayed?

Abstract art representing computer programming

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

Windows Implementation

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

Unix-like Systems Implementation

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.

Cross-platform Solution

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.

This Question is from the Lesson:

User Input in the Terminal

This lesson introduces the fundamentals of capturing user input, using std::cin and std::getline

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

User Input in the Terminal

This lesson introduces the fundamentals of capturing user input, using std::cin and std::getline

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 57 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved