Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不使用getpass(3)在C中获取密码?_C_Passwords - Fatal编程技术网

不使用getpass(3)在C中获取密码?

不使用getpass(3)在C中获取密码?,c,passwords,C,Passwords,我可以使用getpass()获取密码。然而,手册页上说: 此功能已过时。不要使用 它 以POSIX兼容方式从用户终端获取密码而不回显密码的当前方式是什么?[最初我说的是“可移植”,但我的目的是避免使用过时的函数。]您可以使用库读取标准输入,而无需将结果回显到屏幕上。(在获得任何输入之前调用noecho())。该库已存在多年,可在多种平台上使用(可以找到windows版本)在windows上,您可能可以使用所述的SetConsoleModeapi。根据说明,它已过时,因为: getpass()函数

我可以使用
getpass()
获取密码。然而,手册页上说:

此功能已过时。不要使用 它


以POSIX兼容方式从用户终端获取密码而不回显密码的当前方式是什么?[最初我说的是“可移植”,但我的目的是避免使用过时的函数。]

您可以使用库读取标准输入,而无需将结果回显到屏幕上。(在获得任何输入之前调用
noecho()
)。该库已存在多年,可在多种平台上使用(可以找到windows版本)

在windows上,您可能可以使用所述的
SetConsoleMode
api。

根据说明,它已过时,因为:

getpass()
函数不是线程安全的,因为它操作 全局信号状态

计划从X/Open CAE规范的未来版本中撤销
getpass()
功能


这应该适用于linux/macosx,windows版本应该使用

#包括
#包括
#包括
int
主(内部argc,字符**argv)
{
标签、非标签的结构术语;
字符密码[64];
/*禁用回音*/
tcgetattr(文件号(stdin)和oflags);
nflags=标签数量;
nflags.c_lflag&=~ECHO;
nflags.c|lflag |=ECHONL;
if(tcsetattr(文件号(stdin)、TCSANOW和nflags)!=0){
佩罗尔(“tcsetattr”);
返回退出失败;
}
printf(“密码:”);
fgets(密码、sizeof(密码)、标准输入法);
密码[strlen(password)-1]=0;
printf(“您键入了“%s”\n”,密码);
/*恢复终端*/
if(tcsetattr(文件号(stdin)、TCSANOW和of标签)!=0){
佩罗尔(“tcsetattr”);
返回退出失败;
}
返回0;
}

尽管这是一个已经回答过的非常古老的问题,但以下是我一直在使用的内容(与公认的答案非常相似):

#包括
#包括
//
//以下是略作修改的版本,摘自:
// http://www.gnu.org/software/libc/manual/html_node/getpass.html
//
ssize\u t my\u getpass(字符*提示符,字符**lineptr,大小\u t*n,文件*流)
{
结构术语旧,新;
国际nread;
/*关闭回音功能,如果不能,则会失败*/
if(tcgetattr(文件号(流),&u旧)!=0)
返回-1;
_新=旧;
_new.c_lflag&=~ECHO;
if(tcsetattr(文件号(流)、TCSAFLUSH和&u新)!=0)
返回-1;
/*显示提示*/
如果(提示)
printf(“%s”,提示符);
/*读取密码*/
nread=getline(lineptr,n,stream);
/*拆下托架返回装置*/
如果(nread>=1&(*lineptr)[nread-1]=='\n')
{
(*lineptr)[nread-1]=0;
nread--;
}
printf(“\n”);
/*还原终端*/
(void)tcsetattr(文件号(流)、TCSAFLUSH和旧文件);
返回nread;
}
//
//测试线束-演示如何调用my_getpass()。
//
int main(int argc,char*argv[])
{
最大尺寸=255;
字符pwd[maxlen];

char*pPwd=pwd;//另一个简单的Windows解决方案。 包括“conio.h”


没有可移植的方法-这在很大程度上取决于您的平台。@Jerry,这不值得…尽管它是传统的,但这是最可移植的方法。对我来说,这似乎是最简单的方法。在尝试stdin之前,您应该先使用/dev/tty,就像使用管道一样,stdin将是管道内容,而不是终端输入。我会ldn不介意在使用字符密码[64]={0};或者如果它是可重入的
password[strlen(password)-1]=0;
-这是非常错误的。
password[strlen(password)-1]=0;
只有在新行存在时才会删除它,否则它会错误地删除密码的最后一个字符。
password[strcspn](password,“\n”)]='\0'
。我制作了一个简单的curses应用程序(自从我使用curses以来,它已经过时了好几年),并发现当我使用initscr()时,它清除了屏幕。可能有一些方法可以解决这个问题,但快速阅读手册页后并不明显。它已从POSIX/Single UNIX(X/Open的继承者)中退出从2001年开始。这是一个怎样的答案?这真的应该是一个注释。我是古斯塔。这甚至可以让你从命令行输入密码;但是,如果你要这样做,你可能不想打印密码提示。
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int
main(int argc, char **argv)
{
    struct termios oflags, nflags;
    char password[64];

    /* disabling echo */
    tcgetattr(fileno(stdin), &oflags);
    nflags = oflags;
    nflags.c_lflag &= ~ECHO;
    nflags.c_lflag |= ECHONL;

    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    printf("password: ");
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    printf("you typed '%s'\n", password);

    /* restore terminal */
    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    return 0;
}
#include <termios.h>
#include <cstdio>

//
// The following is a slightly modifed version taken from:
// http://www.gnu.org/software/libc/manual/html_node/getpass.html
//
ssize_t my_getpass (char *prompt, char **lineptr, size_t *n, FILE *stream)
{
    struct termios _old, _new;
    int nread;

    /* Turn echoing off and fail if we can’t. */
    if (tcgetattr (fileno (stream), &_old) != 0)
        return -1;
    _new = _old;
    _new.c_lflag &= ~ECHO;
    if (tcsetattr (fileno (stream), TCSAFLUSH, &_new) != 0)
        return -1;

    /* Display the prompt */
    if (prompt)
        printf("%s", prompt);

    /* Read the password. */
    nread = getline (lineptr, n, stream);

    /* Remove the carriage return */
    if (nread >= 1 && (*lineptr)[nread - 1] == '\n')
    {
        (*lineptr)[nread-1] = 0;
        nread--;
    }
    printf("\n");

    /* Restore terminal. */
    (void) tcsetattr (fileno (stream), TCSAFLUSH, &_old);

    return nread;
}

//
// Test harness - demonstrate calling my_getpass().
//
int main(int argc, char *argv[])
{
    size_t maxlen = 255;
    char pwd[maxlen];
    char *pPwd = pwd; // <-- haven't figured out how to avoid this.

    int count = my_getpass((char*)"Enter Password: ", &pPwd, &maxlen, stdin);

    printf("Size of password: %d\nPassword in plaintext: %s\n", count, pwd);

    return 0;
}
  for (;;) {
  int c = _getch();
  switch (c)
  {
  case '\r':
  case '\n':
  case EOF:
    _putch('\n');
    break;

  default:
    _putch('*'); //mask
    thePassword += char(c);
    continue;
  }
  break;
}