【问题标题】:Password should be printed in * [duplicate]密码应打印在 * [重复]
【发布时间】:2015-03-07 13:03:43
【问题描述】:

在此功能中,如果用户想使用该功能,那么它会要求输入密码,即 crackneedit。当用户输入密码时,它将按原样打印在屏幕上

所以我希望每当有人输入密码时,它都会以 *(星号)打印。我应该使用哪个技巧?

int pvote()
{
    int check;
    char *str = "crackneedit";
    char pass[11];
    printf("Enter your password: ");
    scanf("%s",pass);

    check = strcmp(pass,str);
    if (check == 0)
    {
        printf("\nVote recorded according to parties are:\n");
        printf("PARTY               VOTE\n\n");
        printf("BJP                 %d\n",b);
        printf("CONGRESS            %d\n",c);
        printf("AAP                 %d\n",a);
        printf("OTHER               %d\n",o);
        getch();
        return(0);
    }
    printf("\nACCESS DENIED\n");
    return(0);
}

【问题讨论】:

  • 你有没有尝试过或做过一些研究?
  • 查看:stackoverflow.com/a/6856689/57135,但不要使用“getpass”建议。
  • 使用一点缩进。有各种使用终端的库 - termcap 是自己的
  • 为什么return 使用括号?这不是一个功能。你也可以很容易地让你的程序行为不端只要输入abcdefghijkl就可以了,你还应该正确使用标准函数并且scanf()返回一个值,不要忽略它。
  • @iharob:一些编码标准要求这样做。在我读到的一篇文章中,给出的原因是为了与 whilefor 等始终需要括号的视觉一致性。这可能会或可能不会令人信服,但至少它没有真正的伤害:)

标签: c


【解决方案1】:

您应该使用的技巧是告诉您的操作系统停止回显键盘输入,而是自己回显每个字符。

您的操作系统通常会处理键盘输入,直到输入整行文本,并在屏幕上回显这些字符;然后将输入的整行输入发送到您的应用程序。您需要进行适当的系统调用来关闭已处理的键盘输入,并让您的操作系统将每个键入的字符发送到您的进程(包括光标键、回车键等)。

这样做的细节完全取决于您的操作系统。由于您忘记提及您使用的是哪种操作系统,因此无法提供进一步的建议。

我还应该提到的是,您将需要在您的应用程序中做更多的事情。例如,您不能使用 scanf()。您必须编写代码来处理每个键入的字符,一次一个,手动回显每个字符;自己处理退格,构建字符缓冲区等......

【讨论】:

    【解决方案2】:

    如果我没记错的话,你可以使用termcaps

    每次您检测到(例如使用read)输入时,将其存储在代码中的char * 中,然后在该术语上打印*

    这是最终版本:

    #include <unistd.h>
    #include <termios.h>
    #include <stdio.h>
    
    int                     getch()
    {
      struct termios        oldtc, newtc;
      int                   ch;
    
      tcgetattr(STDIN_FILENO, &oldtc);
      newtc = oldtc;
      newtc.c_lflag &= ~(ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newtc);
      ch = getchar();
      tcsetattr(STDIN_FILENO, TCSANOW, &oldtc);
      return ch;
    }
    
    int             main(int argc, char **argv)
    {
      int           c;
      char          ch[20];
      int           i = 0;
    
      printf("What's your password ?(20 char max.)\n");
      while ((c = getch()) != '\n')
        {
          printf("*");
          ch[i++] = c;
        }
      ch[i] = '\0';
      printf("\nYour password is : [%s]\n", ch);
      return 0;
    }
    

    例子:

    #include <unistd.h>
    #include <termios.h>
    #include <stdio.h>
    
    int                     getch()
    {
      struct termios        oldtc, newtc;
      int                   ch;
    
      tcgetattr(STDIN_FILENO, &oldtc);
      newtc = oldtc;
      newtc.c_lflag &= ~(ICANON | ECHO);
      tcsetattr(STDIN_FILENO, TCSANOW, &newtc);
      ch=getchar();
      tcsetattr(STDIN_FILENO, TCSANOW, &oldtc);
      return ch;
    }
    
    int             main(int argc, char **argv)
    {
        int           ch;
    
      printf("What's your password ?\n");
      while ((ch = getch()) != '\n') // Read 'till you'll type a newline     
          {
          printf("*"); // Print a * instead of what you'll type              
          // Need to store the ch into a char * or whatever.                 
        }
      printf("\n");
      return 0;
    }
    

    【讨论】:

    • 对不起,我没有太多时间,但我去年为学校做了这样的事情:首先:使用 read 循环 1 个字符并将其存储通过使用 termcaps 和ioctl 您可以“捕捉”用户正在输入的内容,因此捕捉它并避免打印字符,而是每次read 读取打印* 然后:当read 读取\n 时退出loop -> 所以你已经输入了所有的用户。
    • @SiddhantSingh 我刚刚添加了一个没有store部分的例子,你可以试试。
    • @SiddhantSingh 我添加了有效的最终版本。请验证它。 ;)
    • 你为他们写别人的代码是非常值得称赞的。如果他真的在 Windows 上,那将是非常荒谬的,这不太可能做任何有用的事情
    猜你喜欢
    • 2019-08-20
    • 2020-01-20
    • 2016-06-02
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2012-05-28
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多