1

I am creating a program in C++ that encrypts text using the Caesar Cipher it allows the user to pick the offset that is used to encrypt at the moment i have on written it for offset 1 but when i use replace()function as part of the STL, rather than replacing them with the specified characters they should be replaced to it replaces them all with the same letter

#include <iostream> #include <string> #include <algorithm> using namespace std; int main() { int Offset; string Message; cout << "What Would You Like To Offset By" << endl; cin >> Offset; cout << "Please Enter The Text You Would Like To Encrypt" << endl; cin >> Message; switch(Offset) { case 1: { replace(Message.begin(), Message.end(), 'a', 'b'); replace(Message.begin(), Message.end(), 'A', 'B'); replace(Message.begin(), Message.end(), 'b', 'c'); replace(Message.begin(), Message.end(), 'B', 'C'); replace(Message.begin(), Message.end(), 'c', 'd'); replace(Message.begin(), Message.end(), 'C', 'D'); replace(Message.begin(), Message.end(), 'd', 'e'); replace(Message.begin(), Message.end(), 'D', 'E'); replace(Message.begin(), Message.end(), 'e', 'f'); replace(Message.begin(), Message.end(), 'E', 'F'); replace(Message.begin(), Message.end(), 'f', 'g'); replace(Message.begin(), Message.end(), 'F', 'G'); replace(Message.begin(), Message.end(), 'g', 'h'); replace(Message.begin(), Message.end(), 'G', 'H'); replace(Message.begin(), Message.end(), 'h', 'i'); replace(Message.begin(), Message.end(), 'H', 'I'); replace(Message.begin(), Message.end(), 'i', 'j'); replace(Message.begin(), Message.end(), 'I', 'J'); replace(Message.begin(), Message.end(), 'j', 'k'); replace(Message.begin(), Message.end(), 'J', 'K'); replace(Message.begin(), Message.end(), 'k', 'l'); replace(Message.begin(), Message.end(), 'K', 'L'); replace(Message.begin(), Message.end(), 'l', 'm'); replace(Message.begin(), Message.end(), 'L', 'M'); replace(Message.begin(), Message.end(), 'm', 'n'); replace(Message.begin(), Message.end(), 'M', 'N'); replace(Message.begin(), Message.end(), 'n', 'o'); replace(Message.begin(), Message.end(), 'N', 'O'); replace(Message.begin(), Message.end(), 'o', 'p'); replace(Message.begin(), Message.end(), 'O', 'P'); replace(Message.begin(), Message.end(), 'p', 'q'); replace(Message.begin(), Message.end(), 'P', 'Q'); replace(Message.begin(), Message.end(), 'q', 'r'); replace(Message.begin(), Message.end(), 'Q', 'R'); replace(Message.begin(), Message.end(), 'r', 's'); replace(Message.begin(), Message.end(), 'R', 'S'); replace(Message.begin(), Message.end(), 's', 't'); replace(Message.begin(), Message.end(), 'S', 'T'); replace(Message.begin(), Message.end(), 't', 'u'); replace(Message.begin(), Message.end(), 'T', 'U'); replace(Message.begin(), Message.end(), 'u', 'v'); replace(Message.begin(), Message.end(), 'U', 'V'); replace(Message.begin(), Message.end(), 'v', 'w'); replace(Message.begin(), Message.end(), 'V', 'W'); replace(Message.begin(), Message.end(), 'w', 'x'); replace(Message.begin(), Message.end(), 'W', 'X'); replace(Message.begin(), Message.end(), 'x', 'y'); replace(Message.begin(), Message.end(), 'X', 'Y'); replace(Message.begin(), Message.end(), 'y', 'z'); replace(Message.begin(), Message.end(), 'Y', 'Z'); replace(Message.begin(), Message.end(), 'z', 'a'); replace(Message.begin(), Message.end(), 'Z', 'A'); cout << Message << endl; break; } } } 
5
  • 2
    Perfect situation to use a debugger. How to debug small programs. Commented Aug 1, 2021 at 19:37
  • 1
    You're replacing a replaced Commented Aug 1, 2021 at 19:46
  • 1
    The code first replaces 'a' with 'b', then replaces 'b' with 'c', then replaces 'c' with 'd', and so on. I'll bet everything is ending up as 'a' or 'A'. Commented Aug 1, 2021 at 19:47
  • Your approach could only works, if you have 1 unused characters (possibly \0) that you can use as a temporary value and then applying change in reverse other. And you would need to do it twice once for uppercase and once for lowercase. However, that kind of code is very slow as you scan the string 52 times multiplied by its length (54 with my adjustment). A much better approach would be to update string one character at a time using some mapping (std::transform or something similar) Commented Aug 2, 2021 at 0:02
  • Also, the fact that you have a switch(Offset) means that you would have a lot of similar code. If you really intent to make 25 or so switch cases, then you clearly need to read a few books on code design. Commented Aug 2, 2021 at 0:19

2 Answers 2

3

The Golden Rule Of Computer Programming states: "Your computer always does exactly what you tell it to do, instead of what you want it to do".

Now let's explore what you told your computer to do.

replace(Message.begin(), Message.end(), 'a', 'b'); 

You told your computer to replace every occurrence of the letter 'a' with the letter 'b'. Your computer will do exactly that. Two statements later:

replace(Message.begin(), Message.end(), 'b', 'c'); 

Here, you told your computer to replace every occurrence of the letter 'b' with the letter 'c'. Your computer will do exactly that. This includes both letter 'b' that were in the original text, as well as all letters that were originally 'a' but are now 'b'. That's because, earlier, you told your computer to change all a-s to b-s, and now you have a bunch of bs, and now all of them are indistinguishable from the other.

In this manner, if you work out, on paper, what is the result of everything you told your computer to do, it becomes obvious why the resulting string always winds up with the same letter (two letters, actually, both uppercase and lowercase).

Your obvious goal here is to replace each letter by the next one, rotated. The correct approach will be fundamentally different, but this explains why the text gets replaced "all with the same letter".

Sign up to request clarification or add additional context in comments.

Comments

0

your text made me curious, so I tried another approach:

Taking the cin as string; Converting chars to (ASCII + offset) % 128 and then cout as chars again. If you're interested, i can provide the code, but don't want to take you the chance, to solve it yourself, (in one of the countless possible ways) :)

3 Comments

Obviously % 128 won't map Z back to A with an offset of 1. Also, other characters like digits and punctuation would be modified...
true, that was a dumb idea, tried to write exceptions and shifting, but might be much easier to go with an array for accepted chars instead.
Got it working using ASCII... I guess there are some more todos.. The logic of datastream and strictness in C++ are really challenging... (And I guess there are much more elegant ways) gist.github.com/BarbWire-1/b7e1060dfecad47e2218e9e9925f60dd

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.