如何使 c 中的函数 getch() 忽略退格键并作为字符输入

How to make the function getch() in c ignore backspace and enter as characters

提问人:melodic_n 提问时间:7/7/2023 最后编辑:Jasonmelodic_n 更新时间:7/7/2023 访问量:65

问:

我制作了一个隐藏用户输入的密码程序,但是当我按退格键擦除字符或按回车键完成输入时,它会将其注册为字符

#include <stdio.h>

void main(){
  char pass[100],gt;
  char password[5]="123456";
  int i;
ps:
  printf("enter password:\n");
  while(gt != '\n') {
    if(pass == password)
      printf("access granted :\n");
    else {
      printf("access denied\n");
      fflush(stdin);
      goto ps;
    }
  }
}
c

评论

2赞 Jason 7/7/2023
fflush(stdin)是未定义的行为。 比较指针地址,而不是指向的内容。你想要或为了那个。我相信这个功能会做你想做的事。 可能意味着不同的东西(取决于使用的系统/库),因为它不是一个标准函数,而是一个完全不同的野兽。pass == passwordstrcmpmemcmpgetcgetch
2赞 001 7/7/2023
另外:使用前未初始化。 需要 7 个字节,而不是 5 个字节。可以重构和消除使用。你从来没有真正读过 stdin。gt"123456"goto
1赞 Lundin 7/7/2023
你是怎么设法编译的?它在多个方面都是无效的 C。
0赞 Weather Vane 7/8/2023
使用 MS VC 的一个优点是它不会回显到控制台,因此您可以输出星号。_getch()
0赞 Andreas Wenzel 7/8/2023
ISO C标准库没有函数。您似乎指的是特定于平台的功能。但是,目前尚不清楚您指的是哪个平台,因为存在多个平台来实现特定于平台的功能。因此,请编辑您的问题,以指定您的问题适用于哪个平台(即操作系统和编译器)。getchgetch

答:

2赞 sn01 7/7/2023 #1

您的代码存在一些问题。该变量在 while 循环中使用之前未初始化。这可能会导致未定义的行为。while 循环条件是检查是否不等于换行符,但循环实际上并没有读取用户的任何输入。这可能会导致无限循环。gtgt\n

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int main() {
    char password[] = "123456";
    char input[100];
    int i = 0;
    printf("Enter password:\n");

    // Disable echoing of input characters
    struct termios old, new;
    tcgetattr(fileno(stdin), &old);
    new = old;
    new.c_lflag &= ~ECHO;
    tcsetattr(fileno(stdin), TCSANOW, &new);

    // Read input until newline character is encountered
    char c = getchar();
    while (c != '\n' && i < 99) {
        if (c == 127) {  // Handle backspace character
            if (i > 0) {
                i--;
                printf("\b \b");
            }
        } else {
            input[i++] = c;
            printf("*");
        }
        c = getchar();
    }
    input[i] = '\0';

    // Restore original terminal settings
    tcsetattr(fileno(stdin), TCSANOW, &old);

    // Compare input to password
    if (strcmp(input, password) == 0) {
        printf("\nAccess granted.\n");
    } else {
        printf("\nAccess denied.\n");
        main(); // Restart the program
    }

    return 0;
}

评论

0赞 Jason 7/7/2023
注意:这是一个 posix 解决方案。如果我必须根据问题中的猜测,用户是否在 Windows 上?getch
0赞 Andreas Wenzel 7/8/2023
@Jason:UNIX 的 curses 库也有一个函数。请参阅此文档。因此,这个问题尚不清楚,因为它指的是特定于平台的功能,而没有指定问题适用于哪个平台。getch
0赞 Andreas Wenzel 7/8/2023
在你的回答中,你写道:--我不同意“可以”这个词。在这种情况下,根据 ISO C11 标准的 §6.3.2.1 ¶2 第 4 句这是未定义的行为。"This can result in undefined behavior."
0赞 chux - Reinstate Monica 7/8/2023
sn01,最好返回 257 个不同的值。此外,请考虑返回时应该发生什么。char c = getchar();int c = getchar();getchar()EOF