CS50 Vigenere - 输出不正确

Posted

技术标签:

【中文标题】CS50 Vigenere - 输出不正确【英文标题】:CS50 Vigenere - Output Incorrect 【发布时间】:2016-04-14 02:21:45 【问题描述】:

我以为我拥有它!我一直在研究 Vigenere 问题并且已经接近但是当我检查时不断收到这个错误。当密钥必须循环回来时,似乎有问题。想法?

这是错误:

:) vigenere.c exists

:) vigenere.c compiles

:) encrypts "a" as "a" using "a" as keyword :( encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword \ expected output, but not "xoqmj, yfz gflkp!\n"

:( encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword \ expected output, but not "CaQAun\n"

:( encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword \ expected output, but not "CAQAON\n"

:) handles lack of argv[1]

:) handles argc > 2

:) rejects "Hax0r2" as keyword

这是我的代码:

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

#define FALSE 0
#define TRUE 1

int main(int argc, string argv[])

    string key = argv[1];

    if (argc!= 2)
    
        printf("please provide only one perameter \n");

        // stop the program
        return 1;
    

    // iterate over the key to make sure its all alpha  
    int i,j;
    for (i = 0, j = strlen(key); i < j; i++)
    
        if (!isalpha(key[i]))
        
            printf("please use only alphanumeric values \n");
            return 1;
        
    

    // now we have a key, "key" from the ONE perameter that is all alpha

    string message = GetString();
    int k = 0;
    int keyindex;

    for (i = 0, j = strlen(message); i < j; i++, k++)
    
        if (isalpha(message[i]))
        
            keyindex = k % strlen(argv[1]);
            // covering the upper case letters
            if (isupper(message[i]))
            
                // covering the upper case letters with upper case key letters

                if isupper(key[i])
                
                    // print cipher according to two upper case
                    int cipher = ((message[i] - 65 + key[keyindex] - 65) % 26)
                        + 65;
                    printf("%c", cipher);
                
                else
                
                    // print according to upper case message lower case key
                    int cipher = ((message[i] - 65 + key[keyindex] - 97) % 26)
                        + 65;
                    printf("%c", cipher);
                
            
            // this is for the non upper case letters
            if (islower(message[i]))
            
                if isupper(key[i])
                
                    // print cipher according to lower case message and
                    // upper case key letter
                    int cipher = ((message[i] - 97 + key[keyindex] - 65) % 26)
                        + 97;
                    printf("%c", cipher);
                
                else
                
                    // print according to lower case message  and lower case key
                    int cipher = ((message[i] - 97 + key[keyindex] - 97) % 26)
                        + 97;
                    printf("%c", cipher);
                
            

        
        // non alpha symbols
        else
        
            printf("%c", message[i]);
        
    

    // end program after iterating
    printf("\n");


【问题讨论】:

【参考方案1】:

你的程序有问题:

1) 应使其无法编译的语法错误:

if isupper(key[i]) -> if (isupper(key[i]))

其中有两个,所以一定要修复它们。

2) 递增k

int k = 0;
...
for (i = 0, j = strlen(message); i < j; i++, k++)

    if (isalpha(message[i]))
    
        keyindex = k % strlen(argv[1]);

有两种方法可以解决这个问题,要么在每个字符上增加k,要么在每个字母上增加k。这个问题的设计者选择了字母,所以我们需要这样做:

int k = 0;
...
for (i = 0, j = strlen(message); i < j; i++)

    if (isalpha(message[i]))
    
        keyindex = k++ % strlen(argv[1]);

3) 既然我们已经定义了 keyindex,就使用它:

if isupper(key[i]) -> if isupper(key[keyindex])

其中有两个,所以一定要修复它们。

应用这些更改和一些样式清理,我们得到:

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

int main(int argc, string argv[])

    if (argc != 2)
    
        printf("please provide only one parameter \n");

        return 1; // stop the program
    

    string key = argv[1];

    // iterate over the key to make sure it's all alpha  

    for (int i = 0, j = strlen(key); i < j; i++)
    
        if (!isalpha(key[i]))
        
            printf("please use only alphanumeric values \n");

            return 1;
        
    

    // now we have a key, "key" from the ONE parameter that is all alpha

    string message = GetString();

    for (int i = 0, k = 0, j = strlen(message); i < j; i++)
    
        if (isalpha(message[i]))
        
            int keyindex = k++ % strlen(key);

            if (isupper(message[i])) // covering the upper case letters
            
                if (isupper(key[keyindex]))
                
                    // print cipher according to both upper case
                    int cipher = ((message[i] - 'A' + key[keyindex] - 'A') % 26) + 'A';
                    printf("%c", cipher);
                
                else
                
                    // print cipher according to upper case message and lower case key
                    int cipher = ((message[i] - 'A' + key[keyindex] - 'a') % 26) + 'A';
                    printf("%c", cipher);
                
            
            else // this is for the non upper case letters
            
                if (isupper(key[keyindex]))
                
                    // print cipher according to lower case message and upper case key letter
                    int cipher = ((message[i] - 'a' + key[keyindex] - 'A') % 26) + 'a';
                    printf("%c", cipher);
                
                else
                
                    // print cipher according to both lower case
                    int cipher = ((message[i] - 'a' + key[keyindex] - 'a') % 26)  + 'a';
                    printf("%c", cipher);
                
            

        
        else // non alpha symbols
        
            printf("%c", message[i]);
        
    

    printf("\n"); // end program after iterating


您的代码重复了很多逻辑,您可以将这些逻辑与微小的更改结合起来——重复的逻辑是难以发现错误潜入代码的一种方式。

【讨论】:

感谢您的帮助!这有很大的不同。很难从代码中退后一步。我会牢记您的见解,继续前进:)

以上是关于CS50 Vigenere - 输出不正确的主要内容,如果未能解决你的问题,请参考以下文章

CS50 Vigenere:错误的循环虽然看起来合乎逻辑?

为啥 Vigenere 失败 (CS50x)?

我的 CS50 Vigenere 代码有啥问题?

cs50 的 Vigenere 密码程序错误

Vigenere.c CS50 浮点异常(核心转储)

Vigenere cs50 Pset2 末尾的额外字符