2011-08-10 70 views
0

嗨,我写了一个简单的c编,只需接受密码,而拨打*隐藏输入。但输入的最后一个字符*没有出现在正确的位置。 的代码如下linux终端输出

int main(){ 
int choice = 0; 
char pass[8]; 
FILE *input; 
FILE *output; 
struct termios initial_settings, new_settings; 

if(!isatty(fileno(stdout))){ 
    fprintf(stderr,"Not a terminal \n"); 
} 
input = fopen("/dev/tty","r"); 
output = fopen("/dev/tty","w"); 
if(!input || !output){ 
fprintf(stderr,"error opening"); 
exit(1); 
} 
tcgetattr(fileno(input),&initial_settings); 
new_settings = initial_settings; 
new_settings.c_lflag &= ~ICANON; 
new_settings.c_lflag &= ~ECHO; 
new_settings.c_cc[VMIN] = 1; 
new_settings.c_cc[VTIME] = 0; 
new_settings.c_lflag &= ~ISIG; 
if(tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) { 
fprintf(stderr,"could not set attributes\n"); 
} 

int count = 0; 
char ch; 
printf("Please enter the password: "); 
while (count<8){ 
ch = fgetc(input); 

if(ch == '\n' || ch == '\r'){ 
break; 
}else{ 
fputc('*',stdout); 
pass[count] = ch; 
count++; 
} 
tcdrain(fileno(stdout)); 
} 


fprintf(output,"you have entered :%s \n",pass); 
tcsetattr(fileno(input),TCSANOW,&initial_settings); 
exit(0); 
} 

输出如下:
请输入密码:* * * * * * *
你输入:12345678
*帕什曼岛@帕什曼岛 - 笔记本电脑:〜$

其8个字符的密码&请注意,7 * s按预期方式出现,但最后一个*出现在main的末尾。

+0

请缩进您的代码 – meagar

回答

1

你混合标准输入输出和另一个流,输出,直接对话的终端。他们有不同的缓冲区,并在不同的时间刷新。你真的应该只使用其中之一。

+0

我尝试使用相同的流输出来显示* s,但他们只在我按下输入后出现。 – dasman

+0

嗯,我使用stdout打印出最后一行,它按预期工作......但为什么'输出'流需要很长时间才能刷新与stdout相比? – dasman

+1

它被缓冲,只有当你退出时,libc才会刷新它,因为你没有明确('fflush(stdout)')或关闭它。 – Keith

0

这是因为你打破你写之前的最后一个*:这么 添加

fputc('*',stdout); 

tcdrain(fileno(stdout)); 
+0

nope ...我得到了相同的结果 – dasman

+0

这很奇怪,因为在你写完最后一个*之前你已经崩溃了。 –