Home > Blockchain >  Issues replacing a char within a c string using string.replace()
Issues replacing a char within a c string using string.replace()

Time:08-24

I am writing a program that uses a substitution cipher. I am trying to replace each char in a string (that the user entered) with a char from another string (the encryption key string). But I am having a bunch of issues doing this with the string.replace() function. It does not replace the the char in the userMessage with the correct char. Although this is not an issue when using a string literal as initialization value for letterReplacement. In addition to this, it somehow temporarily increases the size of the userMessage resulting in the loop running for e.g 5 times in a message 3 char long (no matter how letterReplacement was initialized). I would appreciate any information on why this happens.

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::string userMessage;

    std::cout << "\nWelcome to my Military Grade* Encryption Software!" << std::endl;
    std::cout << "--------------------------------------------------" << std::endl << std::endl;

    std::cout << "Please enter a secret message you would like to encrypt:\n-" << std::endl;
    getline(std::cin, userMessage);
    std::cout << "-" << std::endl << std::endl;

    const std::vector <std::string> encryptionKey {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZT.,<>!? - '",
                                                   "ß?pl ,;0=}okm9)]ijN8([uhb7/{zgv6&ctf%xdrys4$e3w|<2Q>1! #ä-:*GnB"};

    for(size_t i {0}; i < userMessage.size();   i)  // Here we encrypt the Message
    {
         char currentCharInUM {userMessage.at(i)};
         size_t currentKeyPosition {encryptionKey.at(0).find(currentCharInUM)}; //finds the position that currentChar is at in first encryptionKey String
         std::cout << "currentKeyPosition: " << currentKeyPosition << " - " << i << std::endl;

         if(currentKeyPosition == std::string::npos) // is letter in userMessage is not in encryptionKey just keep it (skip iteration)
             continue;

         std::string letterReplacement {encryptionKey.at(1).at(currentKeyPosition)};
         userMessage.replace(i,1,letterReplacement);
    }

    std::cout << userMessage;

    return 0;
}

CodePudding user response:

The first character of 2nd element of the vector encryptionKey 'ß' is equal to 2 bytes. So that when you enter 'a' it returns '├' and when you enter b it returns 'ş'. You can try with another character instead of 'ß'.

CodePudding user response:

If your intention was indeed to store non-ASCII characters, it would have been more advantageous to use a lookup table.

The table could be a std::unordered_map<char, wchar_t> to map the English letters to the encrypted characters:

#include <iostream>
#include <string>
#include <unordered_map>

int main()
{
    // Strings
    const char encryptionKeyA[] =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZT.,<>!? - '";
    const wchar_t encryptionKeyW[] = L"ß?pl ,;0=}okm9)]ijN8([uhb7/{zgv6&ctf%xdrys4$e3w|<2Q>1! #ä-:*GnB";

    // Create the lookup table bassed on the above strings
    std::unordered_map<char, wchar_t> encryptionMap;
    for (int i = 0; i < sizeof(encryptionKeyA);   i)
       encryptionMap[encryptionKeyA[i]] = encryptionKeyW[i];
    
    // Test
    std::string userMessage = "abcTest";

   // The output string
   std::wstring encryptedString;

   // Now go through each character of the userMessage
   for(auto ch : userMessage)
   {
       // If the character exists, append the associated encrypted character
       auto iter = encryptionMap.find(ch);
       if (iter != encryptionMap.end())
           encryptedString  = iter->second;
       else
           encryptedString  = L' ';  // Just append a space if it didn't exist
   } 
   std::wcout << encryptedString;
}

Output:

ss?p1 N8

Note that the output is what is displayed if the locale is English. If the terminal/output were set to German, I would assume that the output would be:

ß?p1 N8

since the first character is the "double-s".

Also note that I am assuming that both the original and encrypted character strings are of the same size (in terms of the number of characters) when building the map. If they're not the same size, then the loop to build the map should be adjusted accordingly.

  •  Tags:  
  • c
  • Related