当前位置: 首页 > 知识库问答 >
问题:

CS50凯撒计划正在运行,但check50表示没有

胡承悦
2023-03-14

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

所需经费如下:

在一个名为caesar的文件中实现你的程序。c在一个叫凯撒的目录中。

程序必须接受单个命令行参数,即非负整数。为了便于讨论,我们把它叫做k。

如果您的程序在执行时没有任何命令行参数,或者有多个命令行参数,那么您的程序应该打印一条您选择的错误消息(使用printf),并立即从main返回一个值1(通常表示错误)。

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

不要假设k小于或等于26。你的程序应该适用于k小于2^31-26的所有非负整数值。换句话说,如果用户为k选择了一个太大或几乎太大的值,无法放入整数,那么您不必担心程序是否最终会崩溃(请记住,整数可能会溢出)但是,即使k大于26,程序输入中的字母字符仍应保持程序输出中的字母字符。例如,如果k是27,

根据ASCII,A不应变成[即使]距离A有27个位置http://www.asciichart.com/[asciichart.com];A应该变成B,因为B离A有27个位置,只要你从Z绕到A。

程序必须输出纯文本:(不带换行符),然后提示用户输入纯文本字符串(使用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个答案

韦昊焜
2023-03-14

检查数字非常麻烦,如果参数不正确,不会导致程序按要求返回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()

此外,您不应该使用硬编码的ASCII值,如90122,而应该使用字符常量,如'a''z',以提高可读性。这样做会使编码循环中的另一个错误更加明显:而(cipher_int

以下是一个修改版本:

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

int main(int argc, string argv[])
{
    // check for a single command line argument
    if (argc != 2) {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    char *arg = argv[1];
    if (*arg == '\0') {
        printf("caesar: key cannot be an empty string\n");
        return 1;
    }
    // check that the argument is a non negative number
    for (size_t i = 0; arg[i]; i++) {
        if (!isdigit((unsigned char)arg[i])) {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }
    // value k is the shift number after ./caesar
    int k = atoi(argv[1]) % 26;

    // get plaintext
    string plain_text = get_string("plaintext: ");
    printf("ciphertext: ");
    for (size_t i = 0; plain_text[i] != '\0'; i++) {
        unsigned char c = plain_text[i];
        // change letters
        if (islower(c)) {
            putchar('a' + ((c - 'a') + k) % 26);
        } else
        if (isupper(c)) {
            putchar('A' + ((c - 'A') + k) % 26);
        } else {
            putchar(c);
        }
    }
    printf("\n");
    return 0;
}

丌官寒
2023-03-14

看来你的包装工作不正常。我发现当我用3作为键并把“敏捷的狐狸跳过懒惰的棕色狗”作为纯文本时,“棕色”变成了“er'q”,而它应该是“eurzq”。我想你在使用

 类似资料:
  • 问题内容: 我通过java进行了凯撒密码,它可以运行,但是在用户输入密钥后不对任何内容进行加密! 这是我的代码 跑: 问题答案: 使用效率不是很高…您可以对值进行整数运算以获得其索引。 我在代码中添加了注释以解释更多信息,但这就是我想出的。 输出应该是这样的

  • 我想知道如何限制加密的ASCII范围从32-126。 这个是用来解密的 我的加密工作得很好(当我引用解密函数时),但我的解密并不像它应该的那样工作。 额外注意:我们只需要在编码时进行右移,给出一个字符串供整个程序加密和解密(“这是C++”) 注意:在添加更多代码描述的过程中

  • 我需要编写一个python、hacker和wow这些单词的加密文本,并且使用不包括使用RAW_INPUT的python中的凯撒密码,距离为3。这是我到目前为止,但我不断得到一个错误消息,我不知道如何修复它。

  • 示例:返回。如果给定的整数值小于0或大于26,则应返回空字符串。 我的问题是,作为回报,它只给我真或假。如何解决这个问题:该方法应该返回一个字符串,其中每个字符都是根据指定的整数值移动的。

  • 我在做凯撒密码,这是我的密码 我尝试使用%来解决这个问题(我也不是100%确定如何使用模运算符),但我没有成功。 文本文件的内容是: