Russian Qt Forum

Qt => Общие вопросы => Тема начата: sergek от Февраль 19, 2014, 10:11



Название: [Решено] Ввод пароля в консоли
Отправлено: sergek от Февраль 19, 2014, 10:11
Коллеги, есть ли стандартные средства для подавления эха (или замены вводимых символов на какой-либо один) при вводе строки в консольном приложении? Нужно для ввода пароля.


Название: Re: Ввод пароля в консоли
Отправлено: Bepec от Февраль 19, 2014, 11:10
Я не совсем понял вопроса. В консоли же символы не заменяемые вроде.



Название: Re: Ввод пароля в консоли
Отправлено: OKTA от Февраль 19, 2014, 11:16
В liunx можно с использованием ф-ий самой консоли, на сколько знаю.


Название: Re: Ввод пароля в консоли
Отправлено: sergek от Февраль 19, 2014, 12:17
Я не совсем понял вопроса. В консоли же символы не заменяемые вроде.
Я не понял ответа :) Т.е. спрятать вывод можно только затерев его другими символами?
А хотелось примерно так, как в QLineEdit c QLineEdit::NoEcho или QLineEdit::Password.

В liunx можно с использованием ф-ий самой консоли, на сколько знаю.
Хочется средствами Qt - программа работает в разных ОС.


Название: Re: Ввод пароля в консоли
Отправлено: OKTA от Февраль 19, 2014, 12:26
Думаю универсального решения не будет. Поток ввода связан уже не с самой программой, а с конкретной ОС, на сколько я понимаю.


Название: Re: Ввод пароля в консоли
Отправлено: Bepec от Февраль 19, 2014, 12:45
Таки да, тут уже консоль нужно терзать. Можно затирать символ сразу после введения как вариант. Хотя тут тоже тонкости есть )


Название: Re: Ввод пароля в консоли
Отправлено: sergek от Февраль 19, 2014, 12:57
Думаю универсального решения не будет. Поток ввода связан уже не с самой программой, а с конкретной ОС, на сколько я понимаю.
Осознал. Что же, остается только printf("\r")?


Название: Re: Ввод пароля в консоли
Отправлено: OKTA от Февраль 19, 2014, 13:02
Работает однако)
Код:
#include <stdio.h>
#include <conio.h>
int main(int argc, char *argv[])
{
        char x[10];

        printf("enter password\n");

        for(int i=0; i<9;i++){
            x[i]=getch();
            printf("*");

            if(x[i]=='\r') {
                //

                x[i+1] = '\0';
                break;
            }
        }
        x[10] = '\0';
        printf("\nthe password is : %s", x);


    return 0;
}


Название: Re: Ввод пароля в консоли
Отправлено: kai666_73 от Февраль 19, 2014, 13:26
Тогда лучше так:

Код:
#include <stdio.h>
#include <conio.h>
int main(int argc, char *argv[])
{
        char x[10];

        printf("enter password\n");

        for(int i=0; i<9;i++){
            x[i]=getch();

            if(x[i]=='\r') {
                //

                x[i+1] = '\0';
                break;
            }
            else
                printf("*");
        }
        x[10] = '\0';
        printf("\nthe password is : %s", x);


    return 0;
}


Название: Re: Ввод пароля в консоли
Отправлено: sergek от Февраль 19, 2014, 13:36
Этот вариант я уже рассматривал. Попробуйте теперь при вводе backspace, esc и т.д. Чтобы их обработать, нужно курсор двигать назад, а это проблема.
Пока виден один вариант - printf("\r"), т.е. полное подавление эха.


Название: Re: Ввод пароля в консоли
Отправлено: Alex Custov от Февраль 19, 2014, 13:43
через нативную консоль, в винде типа того - http://www.cplusplus.com/forum/unices/27735/ . В Linux - getpass()


Название: Re: Ввод пароля в консоли
Отправлено: Bepec от Февраль 19, 2014, 13:50
А в линуксе проще - там что угодно вводи, отображаться правда не будет :D


Название: Re: Ввод пароля в консоли
Отправлено: OKTA от Февраль 19, 2014, 13:57
Полное подавление эхо тоже хорошо  :)


Название: Re: [Решено] Ввод пароля в консоли
Отправлено: sergek от Февраль 19, 2014, 21:17
Итак, коллеги, попробую подвести итоги. Не уверен, что это относится к Qt, но надеюсь, модератор меня не заплюсует.
1. Сделать ввод пароля с отображением маскирующих символов в консоли не получится. Точнее, не получится, если при вводе использовать управляющие символы. Напрример, клавиша bakspace или delete испортит всю картину.
2. Способы сокрытия вводимой информации из командной строки можно разделить на два вида.

Первый способ - выводить поверх эха какие-нибудь символы, например, пробелы. Это обеспечивается перемещением текстового курсора в консоли назад и вывода маскирующего символа.
С управлением положением курсором в консоли обстоит дело не лучше. Если в windows эту проблему можно как-то решить, то в linux вряд ли. Поэтому более или менее приемлемым вариантом остается вывод в стандартный поток символов возврата каретки \r или backspace \b.

Второй способ - подавление эхо-вывода. Т.е. перевод консоли в такой режим, при котором курсор стоит на месте, а в консоль ничего не печатается.

Оба способа платформо-зависимые.
Например, для того, чтобы после ввода каждого символа вернуть каретку назад, нужно использовать небуферизованный ввод с посимвольным чтением. В windows это сделать легко нестандартной функцией getch() из conio.h.
В linux ввод построчный. Т.е. функция getchar() читает стандартный ввод до тех пор, пока не будет нажата клавиша возврата каретки. Но можно перевести консоль в посимвольный режим ввода. Решение я увидел у Nixman: http://www.cyberforum.ru/cpp-linux/thread162276.html#post931906.

Второй способ, на мой взгляд, проще, а потому красивее. Определяются две функции echo(bool) для windows и linux, управляющие включением/выключением эха: http://www.cplusplus.com/forum/general/12256/. Далее ввод пароля делается просто:
Код:
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTextStream in(stdin), out(stdout);
    out << "Enter password:" << endl;

    echo(false);
    QString str=in.readLine();
    echo(true);

    out << endl << "Password: " << str << endl;
    return 0;
}
Я лично буду использовать второй.
Если не последует возражений, то тему закрою.


Название: Re: [Решено] Ввод пароля в консоли
Отправлено: DarkHobbit от Декабрь 26, 2017, 15:38
Спасибо!
Второй способ и вправду выглядит изящным.
А как с макосью? там, скорее всего, будет аналогично линуксу?