2011-08-10 225 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

這很奇怪,因爲在你寫完最後一個*之前你已經崩潰了。 –