Как сделать, чтобы backspace не считался символом?

Итак, я должен зашифровать свое консольное приложение паролем, я сделал что-то, что работает, но есть проблема, backsapce не стирает введенный символ, он также считается за символ, как я могу заставить его выполнять свою работу , чтобы стереть символ?

Это код:

void main()
{
    char password[20], my_password[20] = "password";
    int i;
    char ch;
    system("cls");
    cout << "PASSWORD: ";


    i = 0;
    do
    {
        ch = _getch();
        password[i] = ch;
        if (ch != 27 && ch != 13 && ch != 9)
            cout<<"*";
        else
            break;
        i++;
    } while (i < 19);
    password[i] = '\0';



    if (strcmp(password, my_password) != 0) 
    {
        cout << "\n\nIncorrect password !!!";
        cin.get();
        return;
    }
    cout << "\n\nPassword is correct !";
    cout <<"\n\nThe program is executed !";
    cin.get();
}

Какой тип терминала и операционной системы вы используете?

David Grayson 09.04.2019 18:57

Пожалуйста, не используйте магические числа. Для символов, у которых есть escape-последовательности (например, 13 для возврата каретки, '\r'), используйте эти символы, а для символов, у которых нет escape-последовательностей (например, 27 и 9), по крайней мере, создайте макросы.

Some programmer dude 09.04.2019 19:03

Также обратите внимание, что _getch` возвращает int, как и все стандартные функции чтения символов. Это довольно важно, если вы когда-нибудь захотите сравнить с EOF.

Some programmer dude 09.04.2019 19:04

Наконец, пожалуйста, не добавляйте теги для языков, которые могут показаться похожими, используйте только теги для языка, на котором вы на самом деле программируете. C и C++ — это два очень разных языка. И хотя вы не используете многие функции C++, ваша программа по-прежнему является программой C++, поэтому не должна иметь тега c.

Some programmer dude 09.04.2019 19:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
199
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

"как я могу заставить его делать свою работу, чтобы стереть характер?"

Используйте библиотеку curses. Например, ругает.

Не вмешивайтесь ncurses без необходимости; это инструмент для конкретной области, и для таких простых вещей, как этот, он в лучшем случае перегружен.

0xdd 09.04.2019 19:23

@Ctx Краткосрочный; может быть. Но как только OP захочет делать более сложные вещи, библиотека curses станет удобной (и она также может решить насущную проблему).

Jesper Juhl 09.04.2019 19:36

Вы можете проверить, является ли полученный символ возвратом, если это декремент i, который эффективно удалит последний символ.

    i = 0;
    do
    {
        ch = _getch(); // get the character
        if (ch == DEL || ch == BS) // check for backspace
        {
            i--;
            cout << BS;
        }
        else if (ch >= ' ' && ch <= '~') // check if its valid ASCII
        {
            password[i] = ch;
            cout << "*";
            i++;
        }
        else if (ch == 27 || ch == 13 || ch == 9) // check if entry is complete
        {
            break;
        }


    } while (i < 19);

    password[i] = '\0';

где-нибудь еще

#define BS '\b'
#define DEL 127

Вместо макросов, которые могут разрушить хаос подстановки текста, рассмотрите возможность использования чего-то вроде constexpr char BS = '\b';. Это не будет молча топтаться по BSs, а будет рассматриваться как char, позволяющее компилятору ввести проверку и сделать все остальные сообщения об ошибках и предупреждениях. макрос не может, а '\b' позволяет переносимость на системы, отличные от ASCII (меньше беспокойства, чем раньше, но все же на что следует обратить внимание).

user4581301 09.04.2019 20:38

Спасибо за дополнение, вы правы с общим улучшением использования экранированного символа, а не целого числа. Я изменил макрос на '\b', но пока оставлю его как макрос. Я работаю только с C, я думаю, что OP не должен был помечать C, так как это действительно должен быть только C++.

liamcomp 09.04.2019 20:48

Я даже не видел тег C. Ты прав. Я удалю этот тег через секунду.

user4581301 09.04.2019 20:52
Ответ принят как подходящий
void main()
{
    char password[20], my_password[20] = "password";
    int i;
    char ch;
    system("cls");
    cout << "PASSWORD: ";


    i = 0;
    do
    {
        ch = _getch();
        if (ch == 8)
        {
            i--;
            cout << "\b \b";
            continue;
        }

        password[i] = ch;
        if (ch != 27 && ch != 13 && ch != 9)
            cout << "*";
        else
            break;
        i++;
    } while (i < 19);
    password[i] = '\0';



    if (strcmp(password, my_password) != 0)
    {
        cout << "\n\nIncorrect password !!!";
        cin.get();
        return;
    }
    cout << "\n\nPassword is correct !";
    cout << "\n\nThe program is executed !";
    cin.get();
}

Не самый чистый код, но он работает. Уменьшите значение счетчика, чтобы перезаписать предыдущий символ, и выведите два символа возврата, разделенные пробелом.

Рекомендуем прочитать перед использованием этого ответа: Что такое магическое число и почему оно плохое?

user4581301 09.04.2019 20:40

Другие вопросы по теме