0

I'm trying to create an alphabet cipher in C++. My approach for this problem was creating two unordered maps. 1 with the letters and their according int position in the alphabet, and one opposite table.

When I try to access this unordered map in my function, encrypt, I'm getting an error message:

the map is not declared in this scope.

I'm still new to C++. Initially I tried creating the map above main, but this doesn't seem to work either.

Any suggestions or hints on how to approach a situation like this?

#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
#include <numeric>
using namespace std;

string enCrypt (string str, int x){ //encrypts the input letter with the offset variable (encryption key) x
    int pos = cipherMap.at(str);
    string encrypted;
    if (pos + x < 25){
        encrypted = alphaMap.at(pos + x);
        return encrypted;
    }else{
        pos = 25 - pos;
        encrypted = alphaMap.at(x - pos);
        return encrypted;
    }
}

int main()
{
    vector<string> alphabet(26);
    iota(alphabet.begin(), alphabet.end(), 'A');

    unordered_map<string, int> cipherMap; //map containing the alphabet and the corresponding position of the letter in the alphabet
    for (int i = 0; i < 26; i++){
        cipherMap.insert( { alphabet[i], i });
    }

    unordered_map<int, string> alphaMap; //opposite of earlier mentioned map
    for (int i = 0; i < 26; i++){
        alphaMap.insert( { i , alphabet[i] });
    }

    cout << enCrypt("A", 3); //trying to encrypt letter A, output should be D


    return 0;
}

These are the error messages I'm getting:

D:\Reddit Projects\Encryption Cipher\main.cpp||In function 'std::__cxx11::string enCrypt(std::__cxx11::string, int)':|
D:\Reddit Projects\Encryption Cipher\main.cpp|9|error: 'cipherMap' was not declared in this scope|
D:\Reddit Projects\Encryption Cipher\main.cpp|12|error: 'alphaMap' was not declared in this scope|
D:\Reddit Projects\Encryption Cipher\main.cpp|16|error: 'alphaMap' was not declared in this scope|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

With VKNs explanation I managed to solve the program as follows!

#include <unordered_map>
#include <string>
#include <vector>
#include <numeric>
using namespace std;

struct Cipher{
    Cipher (vector<string> alphabet){
        for (int i = 0; i < 26; i++){
            cipherMap.insert( { alphabet[i], i });
        }
        for (int i = 0; i < 26; i++){
            alphaMap.insert( { i , alphabet[i] });
        }
    }
    string encrypt (string str, int x){
        int pos = cipherMap.at(str);
        string encrypted;
        if (pos + x < 25){
            encrypted = alphaMap.at(pos + x);
            return encrypted;
        }else{
            pos = 25 - pos;
            encrypted = alphaMap.at(x - pos);
            return encrypted;

        }
    }
private:
    unordered_map<string, int> cipherMap;
    unordered_map<int, string> alphaMap;
};

int main()
{

        vector<string> alphabet(26);
        iota(alphabet.begin(), alphabet.end(), 'A');

        Cipher cipher{alphabet};
        cout << cipher.encrypt("A", 3);
}

If anyone else has any tips for conventions or anything else always welcome!

rikietje
  • 61
  • 1
  • 6
  • 3
    `alphaMap` is local to `main`. – 001 Feb 26 '20 at 00:34
  • 1
    The error message says it all: the variables are not declared in the scope in which they are used. Are you familiar with the rules that define scope? – JaMiT Feb 26 '20 at 00:35
  • Here's some documentation on [Scope](https://en.cppreference.com/w/cpp/language/scope) although it might be easier to learn this from [a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Blastfurnace Feb 26 '20 at 01:15
  • Thanks for the comments. Managed to solve it thx to your help. – rikietje Feb 26 '20 at 09:32

1 Answers1

0

Here is your main scope:

vector< string > alphabet(26);

unordered_map cipherMap;

unordered_map alphaMap;

When you call string enCrypt(string str, int x), this is what the function can see in its entry point:

string str;

int x;

You haven't passed either of the unordered_maps to it, so it doesn't know what you're talking about. Reading the function from top to bottom:

int pos

There is a variable called pos which holds an integer.

= cipherMap.at(str);

Which is being assigned to something I don't know about (I only know about string str, int x and int pos at this stage).

There are few ways you can solve this, ranging from passing references to the unordered_maps to the function to having a class handle all this for you (which is probably a better choice). Something like this:

struct Cipher {
    Cipher(string alphabet)
    { //...initializes the unordered_maps
    }

    string encrypt(string str, int x)
    { //......
    }
private:
    unordered_map<string, int> cipherMap;
    unordered_map<int, string> alphaMap;
};

int main()
{
    string alphabet;
    //Initialize your alphabet and do whatever you must
    Cipher cipher{alphabet};
    string encrypted = cipher.encrypt(/* Some other string */);
}

This way, the encrypt function can see the unordered_map member variables of the Cipher class, as it too is a member of Cipher.

vkn
  • 191
  • 12
  • Thank you very much for taking your time to comment! I didn't know something as data structures existed and I really appreciate the effort you took in helping me out with so much details! I managed to got it working =) – rikietje Feb 26 '20 at 09:30