在Linux上的C程序中屏蔽密码字符
我试图创建一个程序,在输入密码时隐藏输入的字符。但我仍然有一个问题,只要我启动程序,“*”字符就会连续写入一个分段错误。这是我编写的代码和程序执行后的行为:在Linux上的C程序中屏蔽密码字符,c,linux,ncurses,stdio,C,Linux,Ncurses,Stdio,我试图创建一个程序,在输入密码时隐藏输入的字符。但我仍然有一个问题,只要我启动程序,“*”字符就会连续写入一个分段错误。这是我编写的代码和程序执行后的行为: #include <stdio.h> #include <curses.h> #define ENTER 13 #define TAB 9 char pwd[100]; int main(){ int i = 0; char ch; printf("Enter your pa
#include <stdio.h>
#include <curses.h>
#define ENTER 13
#define TAB 9
char pwd[100];
int main(){
int i = 0;
char ch;
printf("Enter your password. Hit ENTER to confirm.\n");
printf("Password:");
while(getch() != ENTER){
ch = getch();
pwd[i++] = ch;
printf("* \b");
}
if(ch == ENTER || ch == TAB){
pwd[i] = '\0';
}
printf("\n\nPassword:%s\nLength:%d\n\n", pwd, i);
return 0;
}
#包括
#包括
#定义并输入13
#定义选项卡9
char-pwd[100];
int main(){
int i=0;
char ch;
printf(“输入密码。按Enter键确认。\n”);
printf(“密码:”);
while(getch()!=ENTER){
ch=getch();
pwd[i++]=ch;
printf(“*\b”);
}
如果(ch==输入| | ch==制表符){
pwd[i]='\0';
}
printf(“\n\n密码:%s\n长度:%d\n\n”,pwd,i);
返回0;
}
您应该调用
initscr()开始使用任何ncurses方法之前,请执行代码>。因此,尝试这样做:
int main(){
int i = 0;
char ch;
initscr();
// ...
更多。看起来您正从getch()
返回ERR
这不等于ENTER
,因此循环被输入并重复。最终,您在pwd
中用完了空间,但仍在它之外继续写作。分段错误意味着您试图写入一些不可写入的地址
您还有一个错误,即每个循环调用两次getch()
,即使在修复循环/segfault问题后,也会给您带来麻烦。关于:
while(getch() != ENTER){
ch = getch();
这将在循环中每次传递2个字符。不是你想要的。建议:
while( ( ch = getch() ) != ENTER ){
WINDOW *mainwin;
mainwin = initscr(); /* start the curses mode with default window */
clear() /* clear the default window */
...
raw(); /* stop terminal driver from interpreting key strokes */
cbreak(); /* input chars without waiting for newline */
nodelay( mainwin, true); /* causes getch() to wait for a key rather than returning ERR */
keypad( mainwin, true ); /* program must handle all meta keys including newline */
noecho(); /* stop terminal echo while entering password */
size_t i = 0;
while( i < (sizeof( pwd ) -1) && ( ch = getch() ) != ENTER )
{
pwd[i] = ch;
i++;
printw( "*" );
refresh();
}
echo(); /* resume echoing characters on terminal */
keypad( mainwin, false ); /* stop passing keypad chars to program */
noraw(); /* terminal driver resumes interpreting key strokes */
pwd[i] = '\0'; /* NUL terminate the string */
...
endwin();
要避免在用户输入字符时回显字符,请执行以下操作:
您需要关闭echo
,然后对于用户输入的每个字符,输出一个掩蔽字符,如*
由于数组pwd[]
的长度只有100个字符,因此需要将用户可以输入的字符数限制为99个(为后面的NUL字节留出空间),建议:
while( ( ch = getch() ) != ENTER ){
WINDOW *mainwin;
mainwin = initscr(); /* start the curses mode with default window */
clear() /* clear the default window */
...
raw(); /* stop terminal driver from interpreting key strokes */
cbreak(); /* input chars without waiting for newline */
nodelay( mainwin, true); /* causes getch() to wait for a key rather than returning ERR */
keypad( mainwin, true ); /* program must handle all meta keys including newline */
noecho(); /* stop terminal echo while entering password */
size_t i = 0;
while( i < (sizeof( pwd ) -1) && ( ch = getch() ) != ENTER )
{
pwd[i] = ch;
i++;
printw( "*" );
refresh();
}
echo(); /* resume echoing characters on terminal */
keypad( mainwin, false ); /* stop passing keypad chars to program */
noraw(); /* terminal driver resumes interpreting key strokes */
pwd[i] = '\0'; /* NUL terminate the string */
...
endwin();
WINDOW*mainwin;
mainwin=initscr();/*使用默认窗口启动诅咒模式*/
clear()/*清除默认窗口*/
...
原始();/*停止终端驱动程序解释按键*/
cbreak();/*在不等待换行的情况下输入字符*/
诺德利(梅因温,真的);/*导致getch()等待一个键,而不是返回ERR*/
键盘(mainwin,true);/*程序必须处理包括换行符在内的所有元键*/
noecho();/*输入密码时停止终端回显*/
尺寸i=0;
而(i<(sizeof(pwd)-1)和&(ch=getch())!=ENTER)
{
pwd[i]=ch;
i++;
printw(“*”);
刷新();
}
echo();/*在终端上恢复回显字符*/
键盘(mainwin,false);/*停止向程序传递键盘字符*/
noraw();/*终端驱动程序继续解释按键*/
pwd[i]='\0';/*NUL终止字符串*/
...
endwin();
以上可能有点过分
由于存在一些问题,建议不要使用C库函数:getpass()
如果使用raw()
函数,则程序还需要处理用户的退格(和类似)字符。我尝试过,但在启动程序时得到了这样的结果:输入密码。点击回车确认。密码:(B)0
@tecn603——好的,但这解决了您的问题,对吗?插入initscr()代码>星号不再打印,但程序无论如何都无法运行,如果我插入字符,它们不会被遮挡是的,但这不是您所要求的。:)无论如何,我想你需要打电话给noecho()
。这能回答你的问题吗?我曾设想,分段错误取决于我试图写入其他内存地址,但实际上,即使我不插入任何输入,程序也会尝试写入。从我看到的情况来看,getch()似乎返回了-1,这就是问题所在。