【问题标题】:CS50 PSet 2 - Vigenere - Making sure keyword is alphabeticalCS50 PSet 2 - Vigenere - 确保关键字按字母顺序排列
【发布时间】:2017-06-01 22:53:18
【问题描述】:

我目前正在使用 C 语言在 CS50 中研究 Vigenere 密码。要求是制作一个程序,该程序根据关键字(用户输入两者)对一些明文进行加密。它将基于 Vigenere 密码进行加密。我发现很难用语言描述 Vigenere 密码是什么,所以这里是 CS50 规范中的一个示例:

如果 Vigenère 自己想秘密地向某人说 HELLO,使用 ABC 等关键字,他会用 0 的密钥(即 A)加密 H,用 1 的密钥加密 E(即 B ),而第一个 L 的密钥为 2(即 C),此时他将在关键字中没有字母,因此他将重用(部分)它来用密钥加密第二个 L再次为 0(即 A),再次为键为 1 的 O(即 B)。所以他会把 HELLO 写成 HFNLP。

关键字必须是所有字母组成的字符串,并且必须作为第二个命令行参数给出,即下面我的代码中的 argv[1]。我遇到的问题是,如果它不是按字母顺序排列的,我无法让程序拒绝该键,​​如果它全部是按字母顺序排列的,我就不能继续。我试过这样做(见下面的代码),如果我在 argv[1] 中包含一个数字,它不会返回 printf 错误消息。请问有人可以就什么问题提供一些建议吗?如果格式不是很好,请道歉..

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

// declare command line argument variables
int main(int argc, string argv[])
{

string k = argv[1];

//return error if there aren't two command line arguments
if (argc != 2)
    {
        printf("Usage: ./vigenere k\n");
        return 1;
    }

//make sure key is all alphabetical
for (int i = 0; i < strlen(k); i++)

 {
    if(isalpha(k[i]))
    {
    return 0;
    }

    else
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }
 }
}

我也这样尝试过,而不是上面 for 循环中的内容,但它不起作用:

if(!isalpha(k[i]))
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }

【问题讨论】:

    标签: c if-statement cs50 vigenere


    【解决方案1】:
       if(isalpha(k[i]))
        {
        return 0;
        }
    

    只要argv[1] 中有字母就退出程序。相反,您希望继续循环,直到检查 all 个字符。所以,做:

     for (size_t i = 0; i < strlen(k); i++)
     {
        if(!isalpha(k[i]))
        {
        printf("Please ensure all characters are alphabetical.\n");
        return 1;
        }
     }
    

    您还需要在使用argv[1] 之前将参数检查

    if (argc != 2)
        {
            printf("Usage: ./vigenere k\n");
            return 1;
        }
    
    string k = argv[1];
    ...
    

    【讨论】:

    • 感谢您的帮助 :) 我显然不明白 return 的真正作用。
    • 我修改了if 语句,使其在找到 alpha char 时不会立即中断,而在存在非 alpha char 时立即失败。基本上,当循环完成时,argv[1] 通过了 alpha 测试。
    • 抱歉还有一件事 - size_t 是什么?
    • size_t 是整数类型;使用它而不是int,因为从技术上讲,循环可能会溢出int,因为strlen() 返回size_t。在你的玩具程序中这可能无关紧要,但最好养成使用正确类型的习惯。
    • 古怪的反对意见——实际上,很少有系统,也没有桌面或服务器系统,其中可执行文件没有被告知它的程序名称,所以argc 总是至少一个,甚至当没有传递任何参数时,所以argv[1] 被定义为空指针(因为argv[argc] == NULL)。因此,在这种情况下,可以在检查参数数量之前使用string k = argv[1];。但是,使用argv[2] 不一定是安全的。作为一般策略,您是正确的——在尝试使用之前检查您要使用的参数是否存在。所以,你基本上是对的。