【问题标题】:Why do 2 letters not equal to each other show up as equivalent in C?为什么两个不相等的字母在 C 中显示为等价?
【发布时间】:2021-07-05 21:50:14
【问题描述】:

我正在制作一个对明文进行简单加密并输出加密密文的程序。这是一个以YTNSHKVEFXRBAUQZCLWDMIPGJO 为键的示例。

$ ./substitution YTNSHKVEFXRBAUQZCLWDMIPGJO
plaintext:  HELLO
ciphertext: EHBBQ

如果您想了解更多信息,可以阅读说明here

这是我的代码:

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

string ciphertext_generator(string key,string plaintext);
bool alphabetic_char_checker(string word);
bool alphabetic_char_repeat_checker(string word);


string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Please enter a key\n ");
        return 1;
    }
    if (strlen(argv[1]) != 26)
    {
        printf("The key must contain 26 characters.\n ");
        return 1;
    }
    if (alphabetic_char_checker(argv[1]) == false)
    {
        printf("The key must only contain alphabetic characters.\n ");
        return 1;
    }
    else if (alphabetic_char_repeat_checker(argv[1]))
    {
        printf("The key must not contain repeated characters.");
        return 1;
    }


    string plaintext = get_string("plaintext: ");
    string ciphertext = ciphertext_generator(argv[1],plaintext);
    printf("ciphertext: %s",ciphertext);
    return 0;
}
string ciphertext_generator(string key,string plaintext)
{
    string ciphertext = plaintext;
    for (int i = 0, k = strlen(ciphertext); i < k; i++)
    {
        bool capital = isupper(ciphertext[i]);
        ciphertext[i] = toupper(ciphertext[i]);
        for (int i2 = 0, a = strlen(alphabet); i2 < a; i2++)
        {
            if (plaintext[i] == alphabet[i2])
            {
                if (capital == true)
                {
                    ciphertext[i] = key[i2];
                }
                else
                {
                    ciphertext[i] = tolower(key[i2]);
                }
            }
        }
    }
    return ciphertext;
}

bool alphabetic_char_checker(string word)
{
    for (int i = 0, w = strlen(word); i < w; i++)
    {
        word[i] = toupper(word[i]);
        if (word[i] < 'A' || word[i] > 'Z')
        {
            return false;
        }
    }
    return true;
}
bool alphabetic_char_repeat_checker(string word)
{
    for (int i = 0, w = strlen(word); i < w; i++)
    {
        word[i] = toupper(word[i]);
        for (int i2 = 0; i2 < w; i2++)
        {
            if (word[i] == word[i2])
            {
                return false;
            }
        }
    }
    return true;
}

我的问题在于ciphertext_generator 函数,它接受密钥和明文并输出加密的密文。这里发生的是它遍历明文中的所有字母,然后对于每个字母,它遍历整个字母表,检查明文中的字母是否在字母表中,并计算它在字母表中的哪个索引,然后是然后用作密钥的索引,然后在密文字符串中相应地替换。

这里的问题是,在明文的第一个字母上迭代字母表的每个字母,它在正确的索引 N 处正确找到并替换正确的字母,但它也替换了明文,而不仅仅是密文.

我不是想解决这个问题,只是想了解发生了什么,因为我已经调试过了。接下来发生的是第一个字母不断迭代字母表的其余部分,并且直到找到 N,然后用字母表中的正确字母替换它,但也用纯文本替换它。

**

问题

为什么我只设置了密文,明文会捡起字母?

【问题讨论】:

  • string ciphertext = plaintext; 这使得ciphertext 指向与plaintext 相同的内存。对ciphertext 内存内容所做的任何更改也会对plaintext 生效(因为它们是相同的)。这正是您所观察到的。
  • 在 CS50 中,string 只是 typedefchar*。所以你刚刚创建了ciphertext 作为指向plaintext 的指针,(指针只是一个普通变量,它保存其他东西的地址作为它的值)ciphertextplaintext 都保存相同的地址。如果您对其中一个指向的内存进行更改,另一个也将反映该更改。也许CS50x - PSET2- Substitution 可以提供另一种解决问题的方法(这里的错误输出也有同样的问题......)

标签: c cs50


【解决方案1】:

回答问题

为什么我只设置了密文,明文会捡起字母?

在你的函数ciphertext_generator的第一行它说string ciphertext = plaintext;这行表明密文变量将等于明文变量,这意味着密文的内存指向与明文相同的内存,因此对密文所做的任何更改将应用于明文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    相关资源
    最近更新 更多