【问题标题】:Undefined identifier/ undeclared未定义标识符/未声明
【发布时间】:2020-06-17 14:46:41
【问题描述】:

我最近开始使用 C++,我想创建一个可以调用的简单的终止密码函数,但是因为我从我的 python 程序中复制了编码结构,我似乎收到了 4 个错误和 2 个警告。模式位是一个布尔值,其中 true 是加密,false 是解密(它在 python 上工作,所以嘿):)。

我创建“int”所在的函数的第一个,它说“标识符“in”未定义”

同一行中的第二个说“预期为')'”

第三个是在 3 个 if 语句之后,表示“标识符“CharPos”未定义”,即使它已定义

和 Forth 在同一行说“'CharPos':未声明的标识符”

#include <iostream>
#include <fstream>
#include <string>

std::string Encryption(std::string Password, int Key, bool Mode) {
    std::string Alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
    std::string EncryptPass = "";
    if (Key > 36) {
        Key = Key % 36;
    }
    for (int X = 0; X < Password.length(); X++) {
        if (Password.at(X) == ' ') {
            EncryptPass = EncryptPass + " ";
        }
        else {
            for (int Y = 0; Y < 36; Y++) {
                if (Password.at(X) == Alphabet.at(Y)) {
                    if (Mode == true) {
                        int CharPos = Y + Key;
                        if (CharPos > 35) {
                            CharPos = CharPos - 36;
                        }
                    }
                    if (Mode == false) {
                        int CharPos = Y - Key;
                        if (CharPos < 0) {
                            CharPos = CharPos + 36;
                        }
                    }
                    if (Mode != true and Mode != false) {
                        int CharPos = 0;
                    }
                    char CharPos2 = CharPos;
                    char EncryptChar = Alphabet.at(CharPos2);
                    EncryptPass = EncryptPass + EncryptChar;
                }
            }
        }
    }
    return EncryptPass;
}

任何帮助将不胜感激

【问题讨论】:

  • 在有错误的每一行旁边加上注释,而不是描述错误的位置。此外,粘贴每个错误的完整错误消息。
  • int CharPos = 0; 毫无意义。请记住,当您击中第一个 } 时,范围就会消失
  • char CharPos2 = CharPos; 编译器是正确的 CharPos 在这一行没有定义。您在三个不同的范围内定义了 3 个 CharPos 变量 {} 已启用。
  • 我很确定您的 Alphabet 没有 94 个字符。
  • CharPos 在循环结束时将始终为0,因为Mode != true or Mode != false 始终为真。

标签: c++ caesar-cipher


【解决方案1】:

如上所述,代码中的主要问题是 CharPos 在每个 if 子句中重新定义。

你把int CharPos = ...放在每一个地方,你都会创建一个new变量,尽管它的名字对你来说很相似,但是对于编译器来说,有三个unique变量这个名字的。为了在所有作用域 - 变量环境中使用相同的变量,您应该在第一个公共作用域中定义它一次这意味着,在if - else 子句之前的for 循环中。

另外,如上所述,Mode != true || Mode != false 等价于true

我重写了您的代码以确保安全、实现所需的加密并且更具可读性 (IMO)。


std::string encrypt(const std::string& word, std::size_t shift_amount, bool should_shift_up)
{
    static const std::string alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";

    assert (shift_amount <= alphabet.size()); // makes no sense having shift > alphabet size!

    std::string encrypted_word(word.size(), '\0');

    for (std::size_t idx = 0; idx < word.size(); ++idx)
    {
        char original_char = word[idx];
        std::size_t pos_in_alphabet = alphabet.find(original_char);

        std::size_t shifted_char = 'a';
        if (should_shift_up)
        {
            shifted_char = (pos_in_alphabet + shift_amount) % alphabet.size();
        }
        else
        {
            shifted_char = (pos_in_alphabet > shift_amount)  
                         ? pos_in_alphabet - shift_amount
                         : alphabet.size() - shift_amount + pos_in_alphabet;
        }

        encrypted_word[idx] = alphabet[shifted_char];
    }

    return encrypted_word;
}

【讨论】:

  • 如果我要在 for 循环之后使用 Y 定义 CharPos 但在 if - else 语句之前它会在每次循环时创建一个唯一变量,或者我应该在一开始就将其定义为整数,并在此过程中更改它。它为密码中的每个字母循环遍历字母表中的每个字母
  • @Evorage 如果您在定义时对其进行初始化,它将在每次循环运行时重新初始化它,在这种情况下似乎很好。我看不出在循环之外定义它有什么好处,因为它不需要在任何其他地方知道!
  • 再次感谢,当我进行测试时,一切似乎都运行良好,但无论我使用什么密钥,它都会将加密密码的最后一个字母返回为 0 - std::string Password = Encryption (“你好”,1,真); //测试
  • 把最后一个字母改成1(不知道能不能编辑cmets)
  • @Evorage 确实有一个bug,现在看看代码,它按预期工作! (此外,您可以通过按评论旁边的蓝色Edit 文本来编辑您的cmets(但如果我评论了您就无法编辑它,只能删除!)。
【解决方案2】:

您对某些变量的范围有一些问题,例如:char CharPos2 = CharPos; charPos 不再在范围内,因此实际上是无效分配。

因此,不要在每个 if else 中定义一个新的 CharPost,而是在之前声明它并在每个 if 检查中重新分配它,例如:

if (Password.at(X) == Alphabet.at(Y)) {
    int CharPos = 0;
    if (Mode == true) {
        CharPos = Y + Key;
        if (CharPos > 93) {
            CharPos = CharPos - 94;
        }
    }
    if (Mode == false) {
        CharPos = Y - Key;
        if (CharPos < 0) {
            CharPos = CharPos + 94;
        }
    }
    if (Mode != true or Mode != false) {
        CharPos = 0;
    }
    char CharPos2 = CharPos;
    char EncryptChar = Alphabet.at(CharPos2);
    EncryptPass = EncryptPass + EncryptChar;
}

但除此之外,你的代码被破坏了......所以只有转译在这里不起作用......

看这里:

std::string Alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
...
for (int Y = 0; Y < 94; Y++) {
    if (Password.at(X) == Alphabet.at(Y)) {

字母 at(Y) 将在值高于 36 时爆炸...

【讨论】:

  • 奇怪的名字(对不起)谢谢我已经将我的原始帖子编辑为实际值 36(94 来自我的 python 脚本,它使用字母变量中的符号将其长度设为 94)
  • offtopic:您可以使用 @ 引用/回复并让 stackoverflow 建议此人的姓名...
  • 我从来没有真正使用过堆栈溢出,ontopic - 我使用 - std::string Password = Encryption("Hello", 1, true); 进行了几次测试它总是将加密密码的最后一个值返回为 1,有什么想法吗?
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 2012-05-28
  • 2021-06-07
相关资源
最近更新 更多