CS50 凯撒密码错误

发布于 2025-01-10 01:01:58 字数 1796 浏览 5 评论 0原文

好吧,所以我完全被难住了。我无法理解为什么这个程序的输出每次都表现得好像有一个随机密钥。

该程序:

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

int main(int argc, string argv[])
{
    string sKey = argv[1];
// Make sure program was run with just one command-line argument
    if (argc != 2 || atoi(argv[1]) < 0)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

//Counts length of string and checks if all chars are digits
    int counter = 0;
    for (int i = 0; i < strlen(sKey); i++)
    {
        if isdigit(sKey[i])
        {
            counter++;
        }
    }

//Checks if the key is a number
    if (counter != strlen(sKey))
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

// Convert argv[1] from a `string` to an `int`
    int key = (int)sKey;

// Prompt user for plaintext
    string plaintext = get_string("Plaintext:  ");
    printf("Ciphertext: ");
    for (int i = 0; i < strlen(plaintext); i++)
    {
        if (isalpha(plaintext[i]) && isupper(plaintext[i]))
        {
            printf("%c", (((plaintext[i] - 'A') + key) % 26) + 'A');
        }
        else if (isalpha(plaintext[i]) && islower(plaintext[i]))
        {
            printf("%c", (((plaintext[i] - 'a') + key) % 26) + 'a');
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
    printf("\n");
}

将输出以下内容:

caesar/ $ ./caesar 1
Plaintext:  Hello, I'm Justin.
Ciphertext: Fcjjm, G'k Hsqrgl.
caesar/ $ ./caesar 1
Plaintext:  Hello, I'm Justin.
Ciphertext: Pmttw, Q'u Rcabqv.

这似乎是由于模运算符,因为当我隔离它时,我可以重新创建问题。它是我包含的库之一吗?我自己解决了这个问题,最后在 youtube 上查找解决方案,结果发现我的解决方案执行了与正确解决方案相同的操作。我一定是错过了什么。

谢谢

Okay, so I am completely stumped. I cannot understand why this programs output acts as if there is a random key everytime.

This program:

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

int main(int argc, string argv[])
{
    string sKey = argv[1];
// Make sure program was run with just one command-line argument
    if (argc != 2 || atoi(argv[1]) < 0)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

//Counts length of string and checks if all chars are digits
    int counter = 0;
    for (int i = 0; i < strlen(sKey); i++)
    {
        if isdigit(sKey[i])
        {
            counter++;
        }
    }

//Checks if the key is a number
    if (counter != strlen(sKey))
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

// Convert argv[1] from a `string` to an `int`
    int key = (int)sKey;

// Prompt user for plaintext
    string plaintext = get_string("Plaintext:  ");
    printf("Ciphertext: ");
    for (int i = 0; i < strlen(plaintext); i++)
    {
        if (isalpha(plaintext[i]) && isupper(plaintext[i]))
        {
            printf("%c", (((plaintext[i] - 'A') + key) % 26) + 'A');
        }
        else if (isalpha(plaintext[i]) && islower(plaintext[i]))
        {
            printf("%c", (((plaintext[i] - 'a') + key) % 26) + 'a');
        }
        else
        {
            printf("%c", plaintext[i]);
        }
    }
    printf("\n");
}

Will output this:

caesar/ $ ./caesar 1
Plaintext:  Hello, I'm Justin.
Ciphertext: Fcjjm, G'k Hsqrgl.
caesar/ $ ./caesar 1
Plaintext:  Hello, I'm Justin.
Ciphertext: Pmttw, Q'u Rcabqv.

It seems to be due to the modulo operator, because when I isolated it I could recreate the issue. Is it one of my included libraries? I solved the problem on my own and ended up looking up a solution on youtube only to find my solution performed the same operations as the correct solution. I must be missing something.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流绪微梦 2025-01-17 01:01:58

这是因为 int key = (int)sKey; 不会将字符串转换为整数......至少不会以您认为的方式转换。它将字符串指针sKey(内存地址)指向一个整数。由于每次运行程序时,这都可能是不同的地址,这就是它看起来随机的原因。将数字字符串转换为值的正确方法是使用 atoistrtol。程序的第一部分应该是这样的:

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

int main(int argc, string argv[])
{
    string sKey = argv[1];
    int i;

    // Make sure program was run with just one command-line argument
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // Checks if all chars are digits
    for (int i = 0; sKey[i]; i++)
        if (!isdigit(sKey[i]) break;

    // If the key contains any non-digits, error
    if (sKey[i])
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // Convert argv[1] from a `string` to an `int`
    int key = atoi(sKey);

// The rest should be fine

This is because int key = (int)sKey; does NOT convert the string to an integer... at least not in the way you think it does. It takes the string pointer sKey (a memory address) to an integer. Since every time you run the progra this can be a different address, this is why it looks random. The correct way to convert a numerical string to a value is using atoi or strtol. The first part of your program should be something like this:

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

int main(int argc, string argv[])
{
    string sKey = argv[1];
    int i;

    // Make sure program was run with just one command-line argument
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // Checks if all chars are digits
    for (int i = 0; sKey[i]; i++)
        if (!isdigit(sKey[i]) break;

    // If the key contains any non-digits, error
    if (sKey[i])
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    // Convert argv[1] from a `string` to an `int`
    int key = atoi(sKey);

// The rest should be fine
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文