Скрыть пользовательский ввод и разрешить только определенные символы

Есть ли способ скрыть пользовательский ввод, когда его запрашивают в C? Например:

char *str = malloc(sizeof(char *));
printf("Enter something: ");
scanf("%s", str);getchar();
printf("\nYou entered: %s", str);

// This program would show you what you were writing something as you wrote it. 
// Is there any way to stop that?

Другое дело, как можно разрешить только определенных персонажей? Например:

char c;
printf("Yes or No? (y/n): ");
scanf("%c", &c);getchar();
printf("\nYou entered: %c", c);

// No matter what the user inputs, it will show up, can you restrict that only 
// showing up if y or n are entered?

person atb    schedule 16.03.2012    source источник
comment
Боковое примечание: char *str = malloc(sizeof(char *)); кажется неправильным. scanf небезопасен для чтения строк C   -  person another.anon.coward    schedule 16.03.2012
comment
возможный дубликат Прочитайте пароль из std::cin (даже если OP не запрашивает по поводу ввода пароля, в принятом посте в связанной ветке показано, как отключить/включить terminal echo)   -  person Filip Roséen - refp    schedule 16.03.2012
comment
забыл упомянуть среду, это какая-то оболочка, совместимая с posix, консоль win или что? Ваш терминал обрабатывает входной буфер, и, на самом деле, нет портативного способа сделать это.   -  person Tomas Pruzina    schedule 16.03.2012


Ответы (2)


    #include <stdio.h>  
#include <termios.h>  
#include <unistd.h>  
#include <errno.h>  
#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)  
int set_disp_mode(int fd,int option)  
{  
   int err;  
   struct termios term;  
   if(tcgetattr(fd,&term)==-1){  
     perror("Cannot get the attribution of the terminal");  
     return 1;  
   }  
   if(option)  
        term.c_lflag|=ECHOFLAGS;  
   else  
        term.c_lflag &=~ECHOFLAGS;  
   err=tcsetattr(fd,TCSAFLUSH,&term);  
   if(err==-1 && err==EINTR){  
        perror("Cannot set the attribution of the terminal");  
        return 1;  
   }  
   return 0;  
}  
int getpasswd(char* passwd, int size)  
{  
   int c;  
   int n = 0;  

   printf("Please Input password:");  

   do{  
      c=getchar();  
      if (c != '\n'||c!='\r'){  
         passwd[n++] = c;  
      }  
   }while(c != '\n' && c !='\r' && n < (size - 1));  
   passwd[n] = '\0';  
   return n;  
}  
int main()  
{  
   char *p,passwd[20],name[20];  
   printf("Please Input name:");  
   scanf("%s",name);  
   getchar();
   set_disp_mode(STDIN_FILENO,0);  
   getpasswd(passwd, sizeof(passwd));    
   p=passwd;  
   while(*p!='\n')  
     p++;  
   *p='\0';  
   printf("\nYour name is: %s",name);  
   printf("\nYour passwd is: %s\n", passwd);  
   printf("Press any key continue ...\n");  
   set_disp_mode(STDIN_FILENO,1);  
   getchar();  
   return 0;  
}  

для линукса

person gdj    schedule 16.03.2012

Для полноты: Нет способа сделать это в C. (то есть на стандартном простом C без каких-либо платформо-зависимых библиотек или расширений.)

Вы не указали, почему вы хотели это сделать (или на какой платформе), поэтому трудно сделать соответствующие предложения. Вы можете попробовать консольную библиотеку пользовательского интерфейса или библиотека графического интерфейса пользователя. Вы также можете попробовать консольные библиотеки вашей платформы. (Windows, Linux)

person aib    schedule 16.03.2012