CS50 Pset2。维吉内尔。大文本到低键,反之亦然问题

Posted

技术标签:

【中文标题】CS50 Pset2。维吉内尔。大文本到低键,反之亦然问题【英文标题】:CS50 Pset2. Vigenere. Upper text to lower key and vice versa problems 【发布时间】:2016-04-07 12:24:00 【问题描述】:

好的。所以,我需要制作一个 Vigenere 密码。当文本和键都是小写的大写时,代码编译得很好。但是当文本和密钥与大小写不同时,代码不起作用。然后它不打印任何东西。例如,当密钥为:aaAA。文本是aBcD。结果是:AD。有人可以给我一个提示吗? :)

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

int main (int argc, string argv[])

    string key = argv [1]; //argv [1] is the key. 0 is compile program
    
    if (argc != 2)
    
        printf ("Please give one key: "); //if there are more or less then 2 argc, then have to try again
    

for (int j = 0, n = strlen (key); j < n; j++)
    if (!isalpha (key [j]))      
    
        printf ("Please give a key in alphabetic characters: ");
        //key must be alphabetic. For loop to check every character of the key. 
        return 1;
    


string text = GetString(); //Get secret message from user

int j = 0;
for (int i = 0, n = strlen (text); i < n; i++)

    if (isupper (text [i]))
    
        if (isupper (key [j]))
        
        /*Minus 65 to make count till 26 from text and key. Use modulo to wrap around key. And modulo to wrap around alphabet.
        Plus 65 to go to correct ASCII character. */
        int u = ((((text [i] - 65) + (key [j % strlen (key)] - 65)) % 26) + 65);
        printf ("%c", u);
        
    
    else if (islower (text [i]))
     
        if (islower (key[j]))
        
        int l = ((((text [i] - 97) + (key [j % strlen (key)] - 97)) % 26) + 97);
        printf ("%c", l);
        
    
    else if (islower (text [i]))
      
        if (isupper (key[j]))
        
        int lu = ((((text [i] - 97) + (key [j % strlen (key)] - 65)) % 26) + 97);
        printf ("%c", lu);
        
    
    else if (isupper (text [i]))
    
        if (islower (key[j]))
        
        int ul = ((((text [i] - 65 + (key [j % strlen (key)] - 97)) % 26) + 65);
        printf ("%c", ul);
        
    
    else
        
        // When character is non alphabetic print it in its original form.
        printf ("%c", text [i]);
        
    j++; 


    printf ("\n");
    return 0;


【问题讨论】:

【参考方案1】:

问题在于您的 if、else-if、else-if... 语句。原因是 if isupper(text[i]) 返回 true,而 if isupper(key[j]) 返回 false,它永远不会评估 else if 语句。你应该这样做

if( isupper(text[i]))
    if(isupper(key[j])) // Both upper
       //do stuff
    
    else if(islower(key[j])) //Here key is lower and text is upper
       //do stuff
    

else if (islower(text[i]))
    if (islower(key[j])) //Both lower
        //do stuff
    
    else if(isupper(key[j])) //Key upper and text lower
        //do stuff
    

else//It's not alpha
    //do stuff


/***************NEW********************/
j = j%strlen(key); //I suggest using this at the end of the loop to avoid key[j] to go out of it's bounds
// j = (j==strlen(key)) ? 0 : j; //Another alternative

另外,如果字符不是 alpha,我认为你不应该增加 j

【讨论】:

好的,非常感谢。现在上下键工作正常。但它不会环绕密钥。该代码第一次运行良好。但是当文本较长时,它不会正确环绕。似乎无法使它工作。有什么建议吗? @Kim 抱歉,问题出在密钥的 if 语句中。你应该使用key[j%strlen(key)] 否则你会超出它的界限。我会更新答案 啊哈,我明白了。非常感谢你的帮助。终于写完了:)

以上是关于CS50 Pset2。维吉内尔。大文本到低键,反之亦然问题的主要内容,如果未能解决你的问题,请参考以下文章

CS50 - pset2 - 维吉尼

Vigenere cs50 Pset2 末尾的额外字符

关于 CS50 pset2 vigenere

我的代码有啥问题? (Vigenere cypher cs50, pset2)

CS50-pset2-替换

如何在不使用 argv 的情况下获取字符串数组 - CS50 pset2