String subscript out of range (Visual Studio 2013) - c++

I understand that questions with this title/problem have been asked numerous times before (here,here and many others). Here is my code followed by what all I have done to remove the error:
CaesarCipher.h
#ifndef CAESARCIPHER_H
#define CAESARCIPHER_H
#include <ctime>
#include <string>
using namespace std;
// Write your class CaesarCipher here.
class CaesarCipher
{
public:
CaesarCipher();
string Encode(string plainString);
string Decode(string encryptedString);
private:
int key1, key2;
char Encode(char normalChar)const;
char Decode(char encodedChar)const;
};
#endif
CaesarCipher.cpp
#include "stdafx.h"
#include "CaesarCipher.h"
using namespace std;
// Implement the member functions of class CaesarCipher.
CaesarCipher::CaesarCipher()
{
//Random initialization of integer key1
//srand(time(0));
srand((unsigned int)time(0));
int value1 = rand() % 10;
int sign1 = rand() % 2;
sign1 = sign1 == 0 ? -1 : 1;
int key1 = value1 * sign1;
//Random initialization of integer key2
//srand(time(0));
srand((unsigned int)time(0));
int value2 = rand() % 10;
int sign2 = rand() % 2;
sign2 = sign2 == 0 ? -1 : 1;
int key2 = value2 * sign2;
}
char CaesarCipher::Encode(char normalChar) const
{
int result=0;
int charValue = normalChar; //get the ASCII decimal value of character
if (charValue == 32) // if characeter is a space, we leave it
{
result = 32;
}
else
{
if (key1 > 0)
{
result = char(int(charValue + key1 - 97) % 26 + 97); // find the integer value of char after rotating it with key1(positive)
}
if (key1 < 0)
{
result = char(int(charValue -key1 - 97) % 26 + 97); // find the integer value of char after rotating it with key1(negative)
}
if (key2 > 0)
{
result += char(int(charValue + key2 - 97) % 26 + 97); // find the updated integer value of char after rotating it with key2(positive)
}
if (key2 < 0)
{
result += char(int(charValue - key2 - 97) % 26 + 97); // find the updated integer value of char after rotating it with key2(negative)
}
}
return result; // returning the integer value which will be typecasted into a char(encoded char)
}
char CaesarCipher::Decode(char encodedChar) const
{
int result = 0;
int charValue = encodedChar; //get the ASCII decimal value of encoded character
if (charValue == 32) // if characeter is a space, we leave it unchanged
{
result = 32;
}
else
{
if (key1 > 0)
{
result = char(int(charValue - key1 - 97) % 26 + 97); // find the integer value of encoded char after rotating it with key1(positive) in opposite direction
}
if (key1 < 0)
{
result = char(int(charValue + key1 - 97) % 26 + 97); // find the integer value of encoded char after rotating it with key1(negative) in opposite direction
}
if (key2 > 0)
{
result += char(int(charValue - key2 - 97) % 26 + 97); // find the updated integer value of encoded char after rotating it with key2(positive) in opposite direction
}
if (key2 < 0)
{
result += char(int(charValue + key2 - 97) % 26 + 97); // find the updated integer value of encoded char after rotating it with key2(negative) in opposite direction
}
}
return result; // returning the integer value which will be typecasted into a char(decrypted char)
}
string CaesarCipher::Encode(string plainString)
{
int length = plainString.length(); //gets the length of the
input string
string encodedString; // variable to hold the final encrypted string
for (int i = 0; i < length; i++)
{
encodedString[i] = Encode(plainString[i]); // encrypting the string one character at a time
}
return encodedString; // return the final encoded string
}
string CaesarCipher::Decode(string encryptedString)
{
int length = encryptedString.length(); //gets the length of the input encrypted string
string decodedString; // variable to hold the final decrypted string
for (int i = 0; i < length; i++)
{
decodedString[i] = Decode(encryptedString[i]); // decrypting the string one character at a time
}
return decodedString; // return the final decoded string
}
I am using two keys to cipher the text (key1 followed by key2), if it helps in any way.
Main.cpp
#include "stdafx.h"
#include "CaesarCipher.h"
#include <fstream>
#include <iostream>
int main() {
// File streams
ifstream fin("input.txt");
ofstream fout("output.txt");
if (!fin.good()) {
cout << "Error: file \"input.txt\" does not exist!" << endl;
return -1;
}
string original[20], encrypted[20], decrypted[20];
int i = 0; // will store the number of lines in the input file
CaesarCipher cipher; // an object of CaesarCipher class
// Read the sentences from the input file and save to original[20].
// Hint: use getline() function.
while (!fin.eof())
{
getline(fin, original[i]); // Reading a line from input.txt file
encrypted[i] = cipher.Encode(original[i]); // Encrypt the sentences and save to encrypted[20]
decrypted[i] = cipher.Decode(encrypted[i]); // Decrypt the sentences and save to decrypted[20]
i++;
}
//first output all the encrypted lines
for (int j = 0; j < i; j++)
{
fout << "Encrypted sentences:\n";
fout << encrypted[j]<<"\n";
}
//now output all the decrypted lines
for (int j = 0; j < i; j++)
{
fout << "Decrypted sentences:\n";
fout << decrypted[j] << "\n";
}
// Close the files and end the program.
fin.close();
fout.close();
cout << "done!";
return 0;
}
The error which i am getting isExpression: string subscript out of range. Now i understand that i am trying to iterate beyond the limits of the string (somewhere probably in CaesarCipher.cpp in Encoder or Decoder function).
I have tried to change the limits on i without any effect.
I have tried to use size() instead of length() (in desperacy inspite knowing they do the same thing).
I would really appreciate if you can pin-point any thing in particular which might be causing this error and i will try and change it by myself and see the results.
And if you can also tell, how to avoid such errors in future that will also be of great value to me.

CaesarCipher::Encode() is not allocating any memory for the character data of encodedString, so the loop has nothing valid to access with encodedString[i]. To fix that, either:
Use string encodedString = plainString; to make a copy of the input string, then the loop can manipulate the copied data:
string CaesarCipher::Encode(string plainString) {
int length = plainString.length(); //gets the length of the input string
string encodedString = plainString; // variable to hold the final encrypted string
for (int i = 0; i < length; i++) {
encodedString[i] = Encode(encodedString[i]); // encrypting the string one character at a time
}
return encodedString; // return the final encoded string
}
Use encodedString.resize(length) to pre-allocate the output string before entering the loop:
string CaesarCipher::Encode(string plainString) {
int length = plainString.length(); //gets the length of the input string
string encodedString; // variable to hold the final encrypted string
encodedString.resize(length); // allocate memory for the final encoded string
for (int i = 0; i < length; i++) {
encodedString[i] = Encode(plainString[i]); // encrypting the string one character at a time
}
return encodedString; // return the final encoded string
}
Use encodedString += plainString[i]; to append characters to the output string and let it grow as needed:
string CaesarCipher::Encode(string plainString) {
int length = plainString.length(); //gets the length of the input string
string encodedString; // variable to hold the final encrypted string
for (int i = 0; i < length; i++) {
encodedString += Encode(plainString[i]); // encrypting the string one character at a time
}
return encodedString; // return the final encoded string
}
The same problem exists in CaesarCipher::Decode() with the decodedString variable.
Also, main() has a buffer overflow if input.txt has more than 20 lines in it. Consider changing the code to use std::vector instead of fixed arrays.
And while (!fin.eof()) is wrong to use. Use while (getline(...)) instead:
// Read the sentences from the input file and save to original[20].
// Hint: use getline() function.
string line;
while (getline(fin, line)) { // Reading a line from input.txt file
original[i] = line;
encrypted[i] = cipher.Encode(original[i]); // Encrypt the sentences and save to encrypted[20]
decrypted[i] = cipher.Decode(encrypted[i]); // Decrypt the sentences and save to decrypted[20]
i++;
}

Related

Run-length decompression using C++

I have a text file with a string which I encoded.
Let's say it is: aaahhhhiii kkkjjhh ikl wwwwwweeeett
Here the code for encoding, which works perfectly fine:
void Encode(std::string &inputstring, std::string &outputstring)
{
for (int i = 0; i < inputstring.length(); i++) {
int count = 1;
while (inputstring[i] == inputstring[i+1]) {
count++;
i++;
}
if(count <= 1) {
outputstring += inputstring[i];
} else {
outputstring += std::to_string(count);
outputstring += inputstring[i];
}
}
}
Output is as expected: 3a4h3i 3k2j2h ikl 6w4e2t
Now, I'd like to decompress the output - back to original.
And I am struggling with this since a couple days now.
My idea so far:
void Decompress(std::string &compressed, std::string &original)
{
char currentChar = 0;
auto n = compressed.length();
for(int i = 0; i < n; i++) {
currentChar = compressed[i++];
if(compressed[i] <= 1) {
original += compressed[i];
} else if (isalpha(currentChar)) {
//
} else {
//
int number = isnumber(currentChar).....
original += number;
}
}
}
I know my Decompress function seems a bit messy, but I am pretty lost with this one.
Sorry for that.
Maybe there is someone out there at stackoverflow who would like to help a lost and beginner soul.
Thanks for any help, I appreciate it.
Assuming input strings cannot contain digits (this cannot be covered by your encoding as e. g. both the strings "3a" and "aaa" would result in the encoded string "3a" – how would you ever want to decompose again?) then you can decompress as follows:
unsigned int num = 0;
for(auto c : compressed)
{
if(std::isdigit(static_cast<unsigned char>(c)))
{
num = num * 10 + c - '0';
}
else
{
num += num == 0; // assume you haven't read a digit yet!
while(num--)
{
original += c;
}
}
}
Untested code, though...
Characters in a string actually are only numerical values, though. You can consider char (or signed char, unsigned char) as ordinary 8-bit integers as well. And you can store a numerical value in such a byte, too. Usually, you do run length encoding exactly that way: Count up to 255 equal characters, store the count in a single byte and the character in another byte. One single "a" would then be encoded as 0x01 0x61 (the latter being the ASCII value of a), "aa" would get 0x02 0x61, and so on. If you have to store more than 255 equal characters you store two pairs: 0xff 0x61, 0x07 0x61 for a string containing 262 times the character a... Decoding then gets trivial: you read characters pairwise, first byte you interpret as number, second one as character – rest being trivial. And you nicely cover digits that way as well.
#include "string"
#include "iostream"
void Encode(std::string& inputstring, std::string& outputstring)
{
for (unsigned int i = 0; i < inputstring.length(); i++) {
int count = 1;
while (inputstring[i] == inputstring[i + 1]) {
count++;
i++;
}
if (count <= 1) {
outputstring += inputstring[i];
}
else {
outputstring += std::to_string(count);
outputstring += inputstring[i];
}
}
}
bool alpha_or_space(const char c)
{
return isalpha(c) || c == ' ';
}
void Decompress(std::string& compressed, std::string& original)
{
size_t i = 0;
size_t repeat;
while (i < compressed.length())
{
// normal alpha charachers
while (alpha_or_space(compressed[i]))
original.push_back(compressed[i++]);
// repeat number
repeat = 0;
while (isdigit(compressed[i]))
repeat = 10 * repeat + (compressed[i++] - '0');
// unroll releat charachters
auto char_to_unroll = compressed[i++];
while (repeat--)
original.push_back(char_to_unroll);
}
}
int main()
{
std::string deco, outp, inp = "aaahhhhiii kkkjjhh ikl wwwwwweeeett";
Encode(inp, outp);
Decompress(outp, deco);
std::cout << inp << std::endl << outp << std::endl<< deco;
return 0;
}
The decompression can't possibly work in an unambiguous way because you didn't define a sentinel character; i.e. given the compressed stream it's impossible to determine whether a number is an original single number or it represents the repeat RLE command. I would suggest using '0' as the sentinel char. While encoding, if you see '0' you just output 010. Any other char X will translate to 0NX where N is the repeat byte counter. If you go over 255, just output a new RLE repeat command

How to set my decode function to take in the encoded string?

I'm working on my decode function and I've hit a wall. I dont know if I should pass in the encode function or create a class. My encode function compresses a string, I need the decode function to take that encoded string and expand it.
I've been told that it was the same as doing the encode function. I'm not sure where to go here.
#include<iostream>
#include<string>
using namespace std;
string encode(string str)
{
string encoding = "";
int count;
for (int i = 0; str[i]; i++)
{
count = 1;
while (str[i]==str[i+1])
{
count++, i++;
}
encoding += to_string(count) + str[i];
}
return encoding;
}
//Im trying to decode the encoded string
//take in a string and count how many of the same characters there are and print
//e.g
// a3b4c1......would be decoded as aaabbbbc
string decode(string in)
{
string decoding = "";
char s;
int count;
for (int i = 0; i<in; i++)
{
count = 1;
if (in[i] == 'A')
count++, i++;
}
}
int main()
{
string str = "ABBCC";
cout << encode(str);
//cout << decode(str);
}
// My encode functions executes as needed. 1A2B2C
Your encoding is not valid because the encoding of "1a" produces "111a" which is also the encoding of 111 consecutive 'a', you need to add a separator between the count and the character
In your decode function you only manage the special case of A and you do not extract the count the encoder put
Note also in
for (int i = 0; i<in; i++)
{
count = 1;
if (in[i] == 'A')
count++, i++;
}
you always reset count to 1
You need to first extract the count (with the problem I signal at the beginning of my answer) then duplicate the letter 'count' times
It is useless to do string encoding = ""; because the constructor of std::string make it empty, can be just string encoding;
You need to decode an encoded string, this is not what you do in your main where you try to decode the initial string
A corrected version can be :
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
string encode(string str)
{
stringstream encoding;
int count;
for (int i = 0; str[i]; i++)
{
count = 1;
while (str[i]==str[i+1])
{
count++, i++;
}
encoding << count << ' ' << str[i];
}
return encoding.str();
}
string decode(string in)
{
stringstream is(in);
string decoding;
int n;
char c;
while (is >> n >> c)
{
while (n--)
decoding += c;
}
return decoding;
}
int main()
{
cout << encode("ABBCC2a") << endl;
cout << decode(encode("ABBCC2a")) << endl;
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra e.cc
pi#raspberrypi:/tmp $ ./a.out
1 A2 B2 C1 21 a
ABBCC2a
Run-length-encoding – but in a very strange way!
encoding += to_string(count) + str[i];
Let's encode string "sssssssssss"; it will result in a string with array representation of
{ '1', '1', 's', 0 } // string "11s"
(I chose this representation deliberately, you'll see later...)
The problem is that you wouldn't be able to encode strings containing digits: "1s" will result in
{ '1', '1', '1', 's', 0 } // string "111s"
but how would you want to distinguish if we need to decode back to "1s" or into a string solely containing 111 s characters?
Try it differently: A character actually is nothing more than a number as well, e. g. letter s is represented by numerical value 115 (in ASCII and compatible, at least), the digit 7 (as a character!) by numerical value 55. So you can simply add the value as character:
encoding += static_cast<unsigned char>(count) + str[i];
There are some corner cases, unsigned char cannot hold numbers greater than 255, so a string having more subsequent equal characters would have to be encoded e. g. as
{ 255, 's', 7, 's', 0 } // 262 times letter s
Note the representation; 255 and 7 aren't even printable characters! Now let's assume we encoded a string with 115 times the letter s:
{ 115, 's', 0 } // guess, as string, this would be "ss"...
To catch, you would simply check explicitly your counter for reaching maximum value.
Now decoding gets much simpler:
size_t i = 0;
while(i < encoded.size())
{
unsigned char n = encoded[i];
++i;
while(n--)
decoded += encoded[i];
++i;
}
Totally simple: first byte always as number, second one as character...
If you insist on numbers being encoded as string (and encode only strings not containing digits), you could use a std::istringstream:
std::istringstream s(encoded);
unsigned int n;
char c;
while(s >> n >> c)
{
while(n--)
decoded += encoded[i];
}
OK, it is not symmetric to your encoding function. You could adapt the latter to be so, though:
std::ostringstream s;
for(;;) // ...
{
unsigned int count = 1;
// ...
s << count << str[i];
}

How do I get alphabet from the user

I have a trouble with this. I writing a code for the "vigenere cipher".
I have text and key. But i want to get alphabet from the user. what the user wants etc:"abcdfgh" or "sdgfjdgkfdsgs" just what the user wants.
So but i can't do it.
How do I get alphabet from the user?
Firstly, i want to do get alphabet from the user.
After, I want it to enter the word and encrypt it. But the words alphabet is user's alphabet.
Here is the codes:
#include <iostream>
#include <string>
using namespace std;
// Bu fonksiyon bir key oluşturur.
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size()) // eğer oluşturulan key boyutu girilen
metnin boyutuna eşitse fonksiyonu durdur.
break;
key.push_back(key[i]);
}
return key;
}
string cipherText(string str, string key) // "/Bu fonksiyon orjinal metni şifreler \"
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// alfabeyi ASCII kodlarina dönüştür:
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// "/Bu fonksiyon şifreli metni orjinal hale getirir\"
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
}
return orig_text;
}
int main()
{
cout << " Sifrelenmesini istediginiz kelimeyi/cumleyi giriniz" << endl;
string str;
getline(cin, str);
//string str = "METINBUGRA";
cout << "Anahtar kelimeyi giriniz." << endl;
string keyword;
getline(cin, keyword);
//string keyword = "ABC";
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
cout << "Sifrelenmis Kelime : "
<< cipher_text << "\n";
cout << "Cozumlenmis kelime : "
<< originalText(cipher_text, key);
system("pause");
return 0;
}
If I correctly understood your question, you want to use a custom alphabet instead of English alphabet. For instance you may add digits.
Instead of actual letters you must operate on numbers: 0, 1, 2, ... N-1, where N is the size of the alphabet. For English alphabet this means you must use 0 instead of A (0x41), 1 instead of B (0x42), ... 25 instead of Z.
If the size of the key is M, the encryption algorithm for letter at position i is:
( L[i] + K[i mod M] ) mod N
Once you have a functional algorithm that operates on numbers, all you have to do is map your input from letters to numbers and your output from numbers to letters.
Mapping numbers to letters is easy; you just have to store the alphabet into a string – this answers your question:
string n_to_letter; // alphabet
//...
int main()
{
//...
cin >> n_to_letter; // read the alphabet
//...
Mapping letters to numbers is probably beyond your current knowledge; you must use a map:
#include <map>
//...
string n_to_letter; // alphabet
map< char, int > letter_to_n;
void init_letter_to_n() //...
If you do not know how to use a map, there is a workaround: just search for the letter in the alphabet string, or use a 256 characters vector/string.
DEMO

Writing program in C++ using Microsoft VS, but I get a debug assertion message here. It runs on cpp.sh and repl.it fine, but not on VS. What can I do?

This function is meant to remove all special characters, numbers, and whitespace from the char array.
// Michael E. Torres II
// Vigenere Cipher
// February 4, 2018
// C++ code to implement Vigenere Cipher
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <sstream>
#include <functional>
using namespace std;
// This function generates the key in
// a cyclic manner until it's length isi'nt
// equal to the length of original text
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size())
break;
key.push_back(key[i]);
}
return key;
}
// This function returns the encrypted text
// generated with the help of the key
string cipherText(string str, string key)
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// convert into alphabets(ASCII)
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// This function decrypts the encrypted text
// and returns the original text
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
transform(orig_text.begin(), orig_text.end(), orig_text.begin(), ::tolower);
}
return orig_text;
}
string removeNonAlpha(char *str)
{
unsigned long i = 0;
unsigned long j = 0;
char c;
while ((c = str[i++]) != '\0')
{
if (isalpha(c)) // this is where the breakpoint is automatically placed
{
str[j++] = c;
}
}
str[j] = '\0';
return str;
}
// Driver program to test the above function
int main(int argc, char *argv[])
{
string keyword = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
stringstream ss;
char a[] = "“I think and think for months and years. Ninety-nine times, the conclusion is false. The hundredth time I am right.” – Albert Einstein “Imagination is more important than knowledge. For knowledge is limited, whereas imagination embraces the entire world, stimulating progress, giving birth to evolution.” – Albert Einstein";
int i = 0;
string str = removeNonAlpha(a);
str.append(512 - str.length(), 'X');
transform(str.begin(), str.end(), str.begin(), ::toupper);
transform(keyword.begin(), keyword.end(), keyword.begin(), ::toupper);
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
transform(cipher_text.begin(), cipher_text.end(), cipher_text.begin(), ::tolower);
transform(key.begin(), key.end(), key.begin(), ::tolower);
string orig = originalText(cipher_text, key);
cout << "Original/Decrypted Text : " << "\n";
for (int i = 0; i < orig.size(); i += 81)
orig.insert(i, "\n");
cout << orig;
cout << "\n\n" << "Ciphertext : " << "\n";
for (int i = 0; i < cipher_text.size(); i += 81)
cipher_text.insert(i, "\n");
cout << cipher_text;
cout << "\n\nPress ENTER key to Continue\n";
getchar();
return 0;
}
The char array works fine with this while loop, so long as there are no special characters [.,%$#!^]. As soon as there are any special characters in the char array, it gives me the debug assertion:
"Program: ...\Projects\ConsoleApplication17\Debug\ConsoleApplication17.exe
File: minkernel\crts\ucrt\src\appcrt\convert\isctype.cpp
Line: 42
Expression: c >= -1 && c <= 255
...
The program '[11048] ConsoleApplication17.exe' has exited with code 3 (0x3)."
If I run this on repl.it or cpp.sh, I get no issues though. I appreciate any help. Thank you.
It isn't done at all. It needs to be cleaned up a lot, but I'm just trying to test it as is.
see https://msdn.microsoft.com/en-us/library/xt82b8z8.aspx
isalpha expects a number between 0 and 0xFF:
The behavior of isalpha and _isalpha_l is undefined if c is not EOF or
in the range 0 through 0xFF, inclusive. When a debug CRT library is
used and c is not one of these values, the functions raise an
assertion.
You need to cast you char to an unsigned char before passing to isalpha.

Loop not processing the last character of a string

Basically, the (Vigenere) decryption works perfectly except for not including the final letter for the decryption. For instance, the decryption for m_text yields 48 letters instead of 49. I even tried to manipulate the loop but it doesn't work out well since i will get a out of range exception with .at(). Any help would be appreciated!
using namespace std;
#include <string>
#include <iostream>
int main()
{
string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string m_text = "ZOWDLTRTNENMGONMPAPXVUXADRIXUBJMWEWYDSYXUSYKRNLXU";
int length = m_text.length();
string key = "DA";
string plainText = "";
int shift = 0;
int shift2 = 0;
//Loop that decrypts
for (int k = 0; k < length-1; k+=2)
{
//Key 1 shift
shift = m_text.at(k) - key.at(0);
//Key 2 shift
shift2 = m_text.at(k+1) - key.at(1);
if (shift >= 0)
{
plainText += ALPHABET.at(shift);
}
else
{
shift += 91;
plainText += (char)shift;
}
if (shift2 >= 0)
{
plainText += ALPHABET.at(shift2);
}
else
{
shift2 += 91;
plainText += (char)shift2;
}
}
cout << plainText << endl;
}
By the looks of things, you are decoding two characters at a time. So when you have 49 characters in your string, there is one left over (which doesn't get processed). If you make m_text 48 characters long, you will notice you get the correct result.
It might be easier to replicate your key to match the length of the message, then do character-by-character decoding.