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

Posted

技术标签:

【中文标题】CS50 Vigenere:错误的循环虽然看起来合乎逻辑?【英文标题】:CS50 Vigenere: wrong loop although SEEMS logical? 【发布时间】:2019-11-13 06:48:35 【问题描述】:

在过去的一个月里,我是一个完全的新手,非常努力地使用这个 pset。充其量我有以下内容,但这不起作用。

认为我的移位函数没问题,我知道目前它被写入最后打印整数,但即使是整数也不是正确的 ASCII。

如果你运行代码,即使明文的长度只有 3 个字符,它也会输出四个整数。请告诉我你的想法?

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int shift (char c); // declaring prototype of a function that converts char into shift value

int main(int argc, string argv[]) // Counting command-line arguments

    if (argc == 2)
    
        string s = argv[1]; // string of user's key
        int l = 0;
        while (s[l] != '0')
        
            l++
        

        int i = 0 // validating user's key
        while (i < l)
    
        if (isalpha(s[i]))
        
            i++;
        
        else 
        
            printf("Usage: ./vigenere keyword\n");
            return 1;
        
    
    string plaintext = get_string("plaintext: "); // prompt for plaintext
    
        printf("ciphertext: ");
        for (int a = 0, n = strlen(plaintext); a < n; a++)
            
                int key = shift(s[l]);
                int ciphertext = (int)plaintext[a];
                    
                        printf("%i + %i", ciphertext, key);
                    
                l++;
            
    printf("\n");
    

else

    printf("Usage: ./vigenere keyword\n");
    return 1;
  

int shift(char c) // Fx shift: getting the integer of key for each char

    int key = (int)c;
    if (65 <= key && key <= 90)
    
        return (key - 65);
    
    else if (97 <= key && key <= 122)
    
        return (key - 97);
    
    else
    
        return 1;
    

【问题讨论】:

CS50 string 的元素不能安全地与isalpha() 等函数一起使用。 string 只不过是一个混淆的char *,而诸如isalpha() 之类的函数采用int 参数。在带有签名的char 的实现上,值将在传递给isalpha() et 之前进行符号扩展。 al.,并且没有正确解释。这是另一个理由放弃 CS50 的愚蠢string 【参考方案1】:

这里有很多事情要做。

    此代码无法在 CS50 Lab 中编译。 由于while (s[l] != '0') 这一行,此代码不接受用户输入。那是在寻找字符零 (0)。意图很可能是寻找空终止符,写成'\0'printf("%i + %i", ciphertext, key); 的输出在视觉上令人困惑,因为它为每个纯文本字符显示 2 个标记。这可能就是为什么它似乎吐出“四个整数,即使明文的长度只有 3shift 中的 if 测试不正确。它应该在两个值之间寻找字符 。在每种情况下,其中一项测试必须是&gt;=。 程序未正确管理键索引。它不应该尝试访问大于键的长度key 索引。由于程序总是增加键索引,它超出了key 的结尾(如果键,它会从 last 字符开始处理!)。这看起来像是一个很好的caesar 移位,其中“键”是一个字符,但对于vigenere,它的构造不正确。它需要实现规范中描述的键索引:

还请记住,每次对字符进行加密时,都需要 移动到 k 的下一个字母,关键字(并环绕到 如果您用尽了关键字的所有字符,则在关键字的开头)。但如果 您不加密字符(例如,空格或标点符号), 不要前进到 k 的下一个字符!

您可能会发现this walkthrough(来自该课程的早期版本)很有帮助。

风格说明:考虑将名为l 的变量更改为其他名称。在阅读代码时,字母 l 与数字 1 无法区分,这使得代码模棱两可且难以理解。

【讨论】:

以上是关于CS50 Vigenere:错误的循环虽然看起来合乎逻辑?的主要内容,如果未能解决你的问题,请参考以下文章

Vigenere CS50 - 需要帮助循环字母

如何在 vigenere cipherkey cs50 pset2 中重用(循环)密钥

cs50 的 Vigenere 密码程序错误

CS50 PSet 2:Vigenere 密码分段错误

我的“Vigenere CS 50”项目运行不佳

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