CS50凯撒程序正在运行,但check50表示不起作用

时间:2020-05-05 13:49:16

标签: c encryption cs50 caesar-cipher

我创建了这个程序,但是在CS50上出现错误,表明我没有正确执行任何操作。

要求如下:

在名为caesar的目录中的名为caesar.c的文件中实现程序。

您的程序必须接受一个命令行参数,一个非负整数。为了讨论起见,我们称其为k。

如果执行的程序没有任何命令行参数或带有多个命令行参数,则您的程序应打印您选择的错误消息(带有printf),并从main返回值1(这通常会表示错误)。

如果命令行参数的任何字符都不是十进制数字,则程序应打印消息用法:./ caesar键,并从main返回值1。

不要假设k小于或等于26。您的程序应该对k小于2 ^ 31-26的所有非负整数值起作用。换句话说,您不必担心如果用户为k选择的值太大或几乎太大而无法容纳int,则程序最终会中断。 (请注意,一个int可能会溢出。)但是,即使k大于26,程序输入中的字母字符也应保留在程序输出中的字母字符。例如,如果k为27,

根据http://www.asciichart.com/[asciichart.com],即使[[ASCII中的距离A距离A 27个位置,A也不应成为[只要您从Z绕到A,A就应该成为B,因为B与A的距离是27个位置。

您的程序必须输出纯文本:(没有换行符),然后提示用户输入纯文本字符串(使用get_string)。

您的程序必须输出密文:(不带换行符),后跟明文的相应密文,明文中的每个字母字符都“旋转”了k个位置;非字母字符应保持不变。

您的程序必须保留大小写:大写字母尽管已轮换,但必须保持大写字母;小写字母虽然可以旋转,但必须保持小写字母。

输出密文后,应打印换行符。然后,您的程序应通过从main返回0退出。

我的代码:

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

int main(int argc, string argv[])
{
    //check if k inputed
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    //value k is the number after ./caesar
    int k = atoi(argv[1]) % 26;
    int x = 0;
    int s = strlen(argv[1]);
    //check if k is a positive integer
    if (k < 0)
    {
        printf("Usage: .caesar key\n");
        return 1;
    }
    else
    {
        //check for arguments
        for (int i = 0; i < s; i++)
        {
            if (isalpha (argv[1][i]))
            {
                continue;
            }
            else if (isalnum (argv[1][i]))
            {
                x++;
            }
            else
            {
                continue;
            }
        }
        if (x != s)
        {
            printf("Usage: ./caesar key\n");
        }
        else if (x == s)
        {
            //get plaintext
            string plain_text = get_string("plaintext: ");
            printf("ciphertext: ");
            for (int y = 0; y <= strlen(plain_text); y++)
            {
                //change letters
                if (isalpha(plain_text[y]))
                {
                    char p = plain_text[y];
                    int cipher_int = p + k;
                    if (isupper(p))
                    {
                        while(cipher_int >= 90)
                        {
                            cipher_int -= 26;
                        }
                            char cipher_text = cipher_int;
                            printf("%c", cipher_text);
                    }
                    if (islower(p))
                    {
                        while(cipher_int >= 122)
                        {
                            cipher_int -= 26;
                        }
                            char cipher_text = cipher_int;
                            printf("%c", cipher_text);
                    }
                }
                else
                {
                    printf("%c", plain_text[y]);
                }
            }
            printf("\n");
        }
    }
    return 0;
}

2 个答案:

答案 0 :(得分:1)

您的数字检查非常麻烦,并且如果参数不正确,也不会导致程序按要求返回1

这是一个更简单的测试:

        //check for arguments
        for (int i = 0; i < s; i++) {
            if (!isdigit((unsigned char)argv[1][i])) {
                printf("Usage: ./caesar key\n");
                return 1;
            }
        }

还请注意,当索引==字符串的长度时,应停止编码循环。因此运算符应为<

另一个问题是如何使用isalpha()<ctype.h>中具有char值的类似函数。这些函数未定义为负值({​​{1}}除外)。某些平台将EOF定义为默认签名,如果用户键入非ASCII文本,则char的行为将不确定。将参数强制转换为isalpha(plaintext[y]),以避免出现此问题。

此外,您不应使用诸如(unsigned char)90这样的硬编码ASCII值,而应使用诸如122'a'这样的字符常量来提高可读性。这样做会使编码循环中的另一个错误更加明显:'z'应该是while(cipher_int >= 90),而if (cipher_int > 'A')应该是while(cipher_int >= 122)

这是修改后的版本:

if(cipher_int > 'z')

答案 1 :(得分:1)

看来您的包装不能正常工作。我发现当我使用3作为键并输入“快狐狸跳过懒惰的棕色狗”时,我发现。作为纯文本,“棕色”在应为“ eurzq”时变为“ eur`q”。我认为您应该在使用包装>=时使用>