2014-07-17 52 views
-3

這是凱撒密碼加密在edx.org cs50x課程pset2中的問題。C:用凱撒密碼中的符號輸出加密,爲什麼? pset2 cs50

我已經用另一種算法解決了這個問題,但這是我的第一次嘗試,我仍然好奇爲什麼在凱撒文本的右側出現所有這些符號。

即。我輸入文字「Testing」,輸出是「Fqefuz�����w����l��B��」,但沒有符號的答案是正確的。

任何人都可以解釋我嗎?

int main(int argc, string argv[]) 
{ 
    bool keyOk = false; 
    int k = 0; 
    do 
    { 
     if(argc != 2) // Checking if the key was correctly entered. 
     { 
      printf("You should enter the key in one argument from" 
       " the prompt(i.e. './caesar <key>').\n"); 
      return 1; 
     } 
     else 
     { 
      k = atoi(argv[1]); // Converting string to int. 
      keyOk = true; // Approving key. 
     } 
    } 
    while(keyOk == false); 

    string msg = GetString(); // Reading user input. 
    char caesarMsg[strlen(msg)]; 

    for(int i=0, n = strlen(msg); i < n; i++) 
    { 

     if((msg[i] >= 'a') && (msg[i] <= 'z')) 
     // Processing lower case characters 
     { 
      caesarMsg[i] = ((((msg[i] - 97) + k) % 26) + 97); 
     } 
     else if((msg[i] >= 'A') && (msg[i] <= 'Z')) 
     // Processing upper case characters 
     { 
      caesarMsg[i] = ((((msg[i] - 65) + k) % 26) + 65); 
     } 
     else 
     { 
      caesarMsg[i] = msg[i]; 
     } 

    } 
    printf("%s", caesarMsg); 
    printf("\n");   
} 
+5

您最近編碼的字符串緩衝區太小了1個字節。您還需要有終止零的空間。 (此外,你甚至不添加終止零。) – usr2564301

+0

可能重複[它是什麼意思是「零終止」](http://stackoverflow.com/questions/2667648/what-does-it - 將被終止的零) – Deduplicator

+0

'char caesarMsg [strlen(msg)];' - >'char caesarMsg [strlen(msg)+1];' – BLUEPIXY

回答

2

問題的根源是C確實有一個完整的,適當的,或第一級「字符串」的數據類型。 C strings實際上是以NUL'\0')(*)字符結尾的字符數組。

string msg = GetString(); // Reading user input. 
    char caesarMsg[strlen(msg)]; 

這相當於

char* msg = GetString(); /* User or library function defined elsewhere */ 

/* calculates the length of the string s, excluding the terminating null 
    byte ('\0') */ 
    size_t len = strlen(msg); 

    char caesarMsg[len]; /* Create an character (byte) array of size `len` */ 

希望這使得它更清楚,爲什麼這部分不能正常工作。我已經添加的變量len是字符串msg中非NUL字符序列的長度。因此,當您創建長度爲len的字符數組caesarMsg時,NUL字符無法存儲。

for循環正確執行,但printf("%s", caesarMsg);將繼續打印字符,直到找到NUL或崩潰。

順便說一句,您可以輕鬆地將最後兩個printf語句簡化爲單個printf語句。

printf("%s\n", caesarMsg); 

字符串和字符數組是混亂的常見來源任何新的C,還有一些不那麼新C.一些其他參考資料:


咆哮:無論誰創造了string的typedef是邪惡/製作一個嚴重的錯誤,通過誤導學生說,以爲C'S字符串是一個「真正的」(或第一級)的數據類型。


(*)NUL是從NULL不同,因爲NULL(空指針)被強制轉換爲指針,以便它的大小相同其它指針,其中作爲NUL是一個空字符(和任一charint的大小)。

+0

邁克爾泰勒,感謝您的出色信息。 在for循環我更改此: N = strlen的(MSG) 此 N = strlen的(MSG)+ 1 和工程就像一個魅力。 謝謝你,我真的很感激這個信息。 – EduDeBacker