2015-09-24 27 views
1

我正在爲我的實驗表製作一個凱撒密碼,並且已經使它能夠加密3練習(Caesar's Cipher),這是練習的要點。但是有一件事情讓我煩惱。首先,如果我把它放在3以外,會有一個尾隨字符。例如,鍵入「malware」,鍵入2。 這是我的代碼:C語言:在我的輸出的最後一個字符後面有一個尾隨字符

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

int main() 
{ 
    char text[100]; 
    int key,i; 

    printf("Please enter a word/sentence (lowercaps) for encrypting :\n "); 
    fgets(text,100,stdin); 
    printf("Please enter the key that you desire : eg:14\n"); 
    scanf("%d", &key); 
    for(i=0;i<strlen(text);i++) 
    { 
     if (key>=26) 
     { 
     key=key%26; 
     } 
     if (text[i]==' ') 
     { 
     continue; 
     } 
     if(text[i]+key>'z') 
     { 
     text[i]-=97; 
     text[i]+=26; 
     text[i]+=key; 
     text[i]%=26; 
     text[i]+=97; 
     } 
     else 
     { 
     text[i]=text[i]+key; 
     } 
    } 

    printf("this is your encrypted text : %s", text); 
} 

我希望我也跟着編碼正確的縮進的方法。得到了很多,因爲那不喜歡的

+0

你是什麼意思到尾隨字符? 尾隨的空格? – Zermingore

+0

@Zermingore不要,特殊字符。 – ameyCU

+0

是的,我假定ASCII是特殊字符。但我不確定它爲什麼會出現。 –

回答

2

代碼是1)未正確檢測何時一個char是小寫字母2)加密的非字母包括從fgets()'\n'其後使OP的「後的字符我輸出的最後一個字符「。

相反:

if (text[i] >= 'a' && text[i]<= 'z') { 
    text[i] = (text[i] - 'a' + key)%26 + `a`; 
} 
else { 
    ; // nothing 
} 

備選地

if (islower((unsigned char) text[i]) { 
    text[i] = (text[i] - 'a' + key)%26 + `a`; 
} 

注:以上取決於char被編碼爲ASCII

不依賴於ASCII的解決方案。

static const char lowercase[] = "abcdefghijklmnopqrstuvwxyz"; 
char *p = strchr(lowercase, text[i]); 
if (p) { 
    int offset = (p - lowercase + key)%26; 
    text[i] = lowercase[offset]; 
} 
+0

如何避免\ n進入fgets的緩衝區?我應該用自己的方式走嗎? –

+0

對於「不依賴於ASCII的解決方案」,您不妨使用'toUpper'。 – usr2564301

+0

我已經找到了相當有趣的解決方案,即使用strcpn [function](http://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input)。這是[鏈接](http://www.freebsd.org/cgi/man.cgi?query=strcspn&sektion=3)對功能 –

0

正如Blake_Lead說,這個「\ 0」字在你的暗號

事實上我錯了有關緩衝區與fgets(長度)加上一個「\ 0改變「
從手冊頁:

終止空字節(」 \ 0' )設置在所述緩衝器中的最後一個字符之後存儲。

所以,你只需要通過類似改變你的測試

if (text[i]==' ') 

if (text[i] < 'A' || text[i] > 'z' || (text[i] > 'Z' && text[i] < 'a')) 
+0

所以,'text'是一個字符串,其他地方應該是'null'。這不能成爲這種行爲的原因。 – ameyCU

0

我將簡化和驗證碼校正到

#include <stdio.h> 

int main() { 
    char text[100]; 
    int key, i; 
    printf("Enter a word/sentence (lowercaps) for encrypting : "); 
    fgets(text, 100, stdin); 
    printf("Enter the key that you desire (eg. 14) : "); 
    scanf("%d", &key); 
    key %= 26; // Pull this out of the loop and remove the unnecessary if 
    for (i = 0; text[i]; ++i) { // Correct the loop condition 
     if (text[i] == ' ') continue; 
     if (text[i] + key > 'z') 
      text[i] = (text[i] - 97 + 26) % 26 + 97; // Simplify 
     else 
      text[i] += key; 
    } 
    printf("Encrypted text : %s\n", text); 
    return 0; 
} 

輸入

Enter a word/sentence (lowercaps) for encrypting : malware 
Enter the key that you desire (eg. 14) : 2 

輸出

Encrypted text : ocnyctg 
+0

實際上,如果'key = 2'和'y'的代碼保持'y'不變,你應該檢查值。 – ameyCU

+1

我一直在尋找這段代碼,並認爲有錯誤,你正在編寫一個額外的字符在'text'中,因爲fgets返回的換行符 –

+1

當text [i] + key>'z'時, '?哎呀!對於像21這樣的更大的按鍵,這會比使用像3的小按鍵更明顯。 –

相關問題