2015-12-05 50 views
1

我有一些從學校練習在C練習,我從昨天開始一直在努力,但我一直對特定的一個很僵硬。C:字符串「吃」的循環(也許)

在這個程序中,它必須被重複最多5次,直到用戶沒有回答「安全問題」:

用戶必須要問3次上衣輸入密碼(初始「ABC123」 ),如果用戶不知道密碼,他必須回答一個安全問題(「你最喜歡的顏色是什麼?」,答案是「無」)2次。如果他/她沒有正確回答,它應該顯示「Acound locked」。並且循環應該終止,或者如果他/她知道安全問題的答案,那麼他/她鍵入一個新的密碼,該密碼應該適用於其餘的循環。

但似乎字符串以某種方式「吃」了一些循環。我使用了getchar(),但它似乎沒有任何效果。另外,我認爲我犯了一個大錯誤 - 而這需要重複5次。

我做錯了什麼?

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

char temp[7]; 
char CODE[7] = "abc123"; 
char pin[7]; 
char safepin[7]; 
char newpin[7]; 
int i=0, p=0, k=0; 

int main() 
{ 

do{ 
    do{ 
     printf("GIVE PASSWORD:\n"); 
     scanf("%s", pin); 
     i++; 
     } while (i<3 && strcmp (pin, CODE) != 0); 

    if (strcmp(pin, CODE) == 0) 
     printf("W E L C O M E !\n"); 
    else 
    { 
      do{ 
      printf("What's your favourite colour?\n"); 
      scanf("%s", safepin); 
      p++; 
      } while (p<2 && strcmp (safepin, "none") != 0); 

     if (strcmp(safepin, "none") == 0) 
      { 
       printf("Type a new password:\n"); 
       scanf("%s", newpin); 
       strcpy(temp, newpin); 
       strcpy(CODE, temp); 
       main(); 
      } 
     else 
      printf("Account Locked\n");  

} 
    printf("***************\n\n"); 
    k++; 
}while(k<5); 

system("pause"); 
return 0;  
} 

UPDATE:

我修改了代碼一點,由於反應(你無不驚歎)和它的作品就像一個魅力,只好像當你有正確的答案最終像,它始終保持打印(提供密碼),由於第一次轉到檢查點,而不是5次打印。有任何想法嗎?

#include <stdio.h>   
#include <stdlib.h> 
#include <string.h> 
int main() 
{ 
char temp[7]; 
char CODE[7] = "abc123"; 
char pin[7]; 
char safepin[7]; 
char newpin[7]; 
int i=0, p=0, k=0; 
int verified = 0; 
i = 0; 
k = 0; 

CHECKPOINT: 

do{  
    do{ 
     printf("GIVE PASSWORD:\n"); 
     scanf("%s", pin); 
     i++; 
     } while (i<3 && strcmp (pin, CODE) != 0); 

    if (strcmp(pin, CODE) == 0){ 
     printf("W E L C O M E !\n"); 
     verified = 1; 
     goto CHECKPOINT; 
     } 
    else 
    {    
      p = 0; 
      do{ 
      printf("What's your favourite colour?\n"); 
      scanf("%s", safepin); 
      p++; 
      } while (p<2 && strcmp (safepin, "none") != 0); 

      if (strcmp(safepin, "none") == 0) 
      { 
       printf("Type a new password:\n"); 
       scanf("%s", newpin); 
       strcpy(temp, newpin); 
       strcpy(CODE, temp); 
       strcpy(pin, CODE); 
       goto CHECKPOINT; 
      } 
      else 
       { 
       printf("Account locked.\n");  
       verified = 1; 
       } 
    } 
printf("***************\n\n"); 
k++; 
}while(k<5 && !verified); 

system("pause"); 
return 0;  
} 
+0

所以當用戶鍵入他的新密碼後,立即在程序要求他給出密碼後。由於密碼已更改,用戶所做的密碼應該工作,然後顯示「W E L C O M E!」 – Coursal

+0

我注意到你將要改變的任務之一就是使用全局變量來處理例程中本地的事物。如果您稍後將main更改爲authenticate_user之類的函數,則這些變量在重用時不會重新初始化,而更糟糕的是會保留敏感信息,這些信息會持續存在於過程中,並可用於程序的其餘部分或知道如何檢查的窺探者正在運行的進程的地址空間。 –

+0

當你說這些字符串看起來像是在「吃」你的循環時,你究竟是什麼意思? –

回答

0

當我運行這個程序,我注意到的是,外環要重複5次不管嘛。您可以通過添加一個名爲'verified'或'correct'(僅使用int值)的標誌來解決此問題,該標誌初始化爲0,並在發出W E L C O M E消息的相同位置設置爲1。然後改變你的外觀以包括對該標誌的檢查,例如,

while(!verified && k<5) 

而且,正如我在評論表明我把所有的變量聲明裏面的「主」的初始化一起。這樣它們在例程中是本地的,並在運行時初始化而不是編譯/鏈接時間。最後,雖然我意識到這是一項任務,而不是您正在編寫的「真實」安全例程,但爲了開發良好的實用習慣 - 我會對變量進行練習(重新初始化),特別是持有驗證的變量密碼,然後在退出之前立即阻止熟練的黑客進行祕密檢查。即使在生產環境中,這對於與安全無關的代碼來說也永遠不會有利,但是當代碼是關鍵安全組件時,您必須考慮這些事情。

我運行你的程序,除了這些東西,它似乎像廣告一樣工作。

+0

所以我做了「驗證」標誌,但現在,每次我輸入一個新的密碼,它都不會接受它。只有第一個(abc123)。 – Coursal

+0

更新:通過(if(strcmp(safepin,「none」)== 0))中的goto CHECKPOINT和變量聲明之後的CHECKPOINT,能夠超過該值。 – Coursal

+0

重構代碼結構以擺脫goto可能是一種很好的做法。你的老師可能會也可能沒有任何關於gotos的說法,但是自從Edsger W. Dijkstra現在出名(或者根據你的觀點臭名昭着)聲明(GO TO被認爲是有害的)之後,他們的使用會受到限制。儘管不要扔掉一個工作程序,但你做了什麼。這是你準時完成你的任務的最佳選擇。我一直是軟件開發人員超過30年,除了狀態機之外,我一方面可以依靠我曾經使用過的許多軟件。 –