I have a task to create an application for encoding and decoding using Atbash cipher. I have done the encoding/decoding thing but another part of the task is to cache the already encoded/decoded strings. Cache should be printable with standard stream operators and should be able to be stored and loaded in/from a file. Could someone help me to do it? Thanks in advance! This is my code by now:
#include <iostream>
#include <string>
using namespace std;
string Atbash_cipher(string message)
{
string upperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string reverseUpperAlpha = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
string lowerAlpha = "abcdefghijklmnopqrstuvwxyz";
string reverseLowerAlpha = "zyxwvutsrqponmlkjihgfedcba";
string cipher = "";
for (int i = 0; i < message.length(); i++)
{
if (message[i] >= 32 && message[i] <= 64 && message[i] >= 173 && message[i] <= 176)
{
cipher += message[i];
}
if (message[i] >= 'A' && message[i] <= 'Z')
{
for (int j = 0; j < upperAlpha.length(); j++) {
if (message[i] == upperAlpha[j])
{
cipher += reverseUpperAlpha[j];
break;
}
}
}
else
{
for (int j = 0; j < lowerAlpha.length(); j++)
{
if (message[i] == lowerAlpha[j])
{
cipher += reverseLowerAlpha[j];
break;
}
}
}
}
return cipher;
}
void menu()
{
int choice;
string message;
do
{
cout << "1. Encrypt message" << endl << "2. Decrypt message" << endl << "0. Exit" <<
endl << "Your choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "Enter message to encrypt: ";
cin.ignore();
getline(cin, message);
cout<< Atbash_cipher(message) <<endl;
break;
case 2:
cout << "Enter message to encrypt: ";
cin.ignore();
getline(cin, message);
cout << Atbash_cipher(message) << endl;
break;
}
} while (choice != 0);
}
int main()
{
menu();
return 0;
}
Related
In the first code I did a Caesar cipher and it is working well. However, i cannot added Vigenere. There is a class and some pointers, but they do not work in the switch-case statement, so I need help.
encryption part is switch case :3
decryption part is switch case :4
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
char message[200], ch;
int i, key;
string k,output,messageV;
int menu(int answer);
int main()
{
int answer;
bool keepLooping = true;
while (keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Caesar \n(2)Vigenere \n ";
cin >> answer;
if (answer == 1)
{
while(keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> answer;
if (answer == 1)
{
answer = 1;
keepLooping = false ;
}
else if(answer == 2)
{
answer = 2;
keepLooping = false;
}
else
{
keepLooping = true;
}
}
}
else if(answer == 2)
{
while(keepLooping)
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> answer;
if (answer == 1)
{
answer = 3;
keepLooping = false ;
}
else if(answer == 2)
{
answer = 4;
keepLooping = false;
}
else
{
keepLooping = true;
}
}
}
else
{
keepLooping = true;
}
}
menu(answer);
}
int menu(int answer)
{
switch (answer)
{
case 1://Caesar Cipher Encryption
cout << "Enter a message to encrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch + key;
if(ch > 'z'){
ch = ch - 'z' + 'a' - 1;
}
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}
message[i] = ch;
}
}
cout << "Encrypted message: " << message;
break;
case 2://Caesar Cipher Decryption
cout << "Enter a message to decrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
message[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch > 'a'){
ch = ch + 'Z' - 'A' + 1;
}
message[i] = ch;
}
}
cout << "Decrypted message: " << message;
break;
case 3:
cout << "CASE 3";
break;
case 4:
cout << "CASE 4";
break;
default:
cout << "There is no choices." << endl;
}
return answer;
}
Vigenere part:
#include <iostream>
#include <string>
using namespace std;
class Vig {
public:
string k;
Vig(string k) {
for (int i = 0; i < k.size(); ++i) {
if (k[i] >= 'A' && k[i] <= 'Z')
this->k += k[i];
else if (k[i] >= 'a' && k[i] <= 'z')
this->k += k[i] + 'A' - 'a';
}
}
string encryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c + k[j] - 2 * 'A') % 26 + 'A'; //added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string decryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c - k[j] + 26) % 26 + 'A';//added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
};
int main() {
char message[200];
string key;
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string encrypt = v.encryption(ori);
string decrypt = v.decryption(encrypt);
cout << "Original Message: "<<ori<< endl;
cout << "Encrypted Message: " << encrypt << endl;
cout << "Decrypted Message: " << decrypt << endl;
}
My suggestion is that you try to find the common patterns in your two programs. For example you have you have to methods to encrypt and decrypt. That could be abstracted into two different classes, perhaps with a common base-class defining the interface (allowing things like polymorphism):
struct Cipher
{
virtual std::string encryption(std::string const&) = 0;
virtual std::string decryption(std::string const&) = 0;
};
class Caesar : public Cipher
{
public:
std::string encryption(std::string const& s) override
{
// TODO: Implement Caesar cipher encryption
}
std::string decryption(std::string const& s) override
{
// TODO: Implement Caesar cipher decryption
}
};
class Vigenere : public Cipher
{
public:
std::string encryption(std::string const& s) override
{
// TODO: Implement Vigenere cipher encryption
}
std::string decryption(std::string const& s) override
{
// TODO: Implement Vigenere cipher decryption
}
};
From this we could create a set of functions to use any cipher (through pointers to the base Cipher class). Lets start with selecting which cipher to use:
Cipher* select_cipher()
{
std::cout << "Please select cipher to use:\n";
std::cout << "1) Caesar\n";
std::cout << "2) Vigenere\n";
int selection;
std::cin >> selection;
if (selection == 1)
{
return new Caesar;
}
else if (selection == 2)
{
return new Vigenere;
}
else
{
return nullptr;
}
}
Now we have a cipher to use, then select what to do:
int select_method()
{
std::cout << "Do you want to encrypt or decrypt?\n";
std::cout << "1) Encrypt\n";
std::cout << "2) Decrypt\n";
int method;
std::cin >> method;
return method;
}
Now we really have everything needed to use any supported cipher and method:
int main()
{
Cipher* cipher = select_cipher();
int method = select_method();
std::string input;
std::string result;
// TODO: Read input string to encrypt or decrypt
if (method == 1)
{
result = cipher->encryption(input);
}
else if (method == 2)
{
result = cipher->decryption(input);
}
std::cout << "Result = " << result << '\n';
}
Do note that this is only a very rough outline, and there are many parts missing (like the actual encryption and decryption algorithms). These are left as an exercise for the readers.
Instead of using if ... else if ... you can of course use switch. But for these simple cases it doesn't really matter, and if ... else if ... is, IMO, easier to read.
I coded it already can you check it too, please ?
#include <iostream>
#include <string>
using namespace std;
class Vig {
public:
string k;
Vig(string k) {
for (int i = 0; i < k.size(); ++i) {
if (k[i] >= 'A' && k[i] <= 'Z')
this->k += k[i];
else if (k[i] >= 'a' && k[i] <= 'z')
this->k += k[i] + 'A' - 'a';
}
}
string Vegencryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c + k[j] - 2 * 'A') % 26 + 'A'; //added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string Vegdecryption(string t) {
string output;
for (int i = 0, j = 0; i < t.length(); ++i) {
char c = t[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;
output += (c - k[j] + 26) % 26 + 'A';//added 'A' to bring it in range of ASCII alphabet [ 65-90 | A-Z ]
j = (j + 1) % k.length();
}
return output;
}
string Cesencryption(string t, int key){
string output;
char ch;
for(int i = 0; t[i] != '\0'; ++i){
ch = t[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch + key;
if(ch > 'z'){
ch = ch - 'z' + 'a' - 1;
}
t[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch + key;
if(ch > 'Z'){
ch = ch - 'Z' + 'A' - 1;
}
t[i] = ch;
}
}
output = t;
return output;
}
string Cesdencryption(string t, int key){
string output;
char ch;
for(int i = 0; t[i] != '\0'; ++i){
ch = t[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
t[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch > 'a'){
ch = ch + 'Z' - 'A' + 1;
}
t[i] = ch;
}
}
output = t;
return output;
}
};
int main() {
char message[200];
string key;
int choice;
cout << "Pick a Choice from the List: \n(1)Caesar \n(2)Vigenere \n ";
cin >> choice;
if(choice == 2) //Vigenere
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> choice;
if (choice == 1)
{
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string encrypt = v.Vegencryption(ori);
cout << "Encrypted Message: " << encrypt << endl;
}
else if (choice == 2)
{
cout << "Key: ";
cin >> key;
cin.ignore();
Vig v(key);
cout << "Enter a message to encrypt: ";
cin.getline(message, 200);
string ori = message;
string decrypt = v.Vegdecryption(ori);
cout << "Decrypted Message: " << decrypt << endl;
}
else
{
cout << "You Exit the Program.";
}
}
else if (choice == 1) //Ceaser
{
cout << "Pick a Choice from the List: \n(1)Encryption\n(2)Decryption \n ";
cin >> choice;
if (choice == 1)
{
int key;
cout << "Enter a message to encrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
Vig v(message);
string ori = message;
string decrypt = v.Cesencryption(ori,key);
cout << "Decrypted Message: " << decrypt << endl;
}
else if (choice == 2)
{
int key;
cout << "Enter a message to dencrypt: ";
cin.ignore();
cin.getline(message, 200);
cout << "Enter key: ";
cin >> key;
Vig v(message);
string ori = message;
string encryption = v.Cesdencryption(ori,key);
cout << "Decrypted Message: " << encryption << endl;
}
else
{
cout << "You Exit the Program.";
}
}
else
{
cout << "You Exit the Program.";
}
}
I have a text file and I passed it to a char array. It was fine when I display in a getline() loop but after going through encryption, only the last line is encrypted and displayed. I have tried to display values in array before entering shift key and what is inside the array is the last line of the text only. What has went wrong? Please help!!
char msg[5000];
string plaintext;
int choice, shift;
char ch;
// Read file into char array
ifstream infile("plaintext.txt");
while (getline(infile, plaintext))
{
strcpy_s(msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
}
cout << endl;
cout << "Enter shift key: ";
cin >> shift; //take the shift as input
cout << "Enter your choice" << endl;
cout << "1.Encryption" << endl;
cout << "2.Decryption" << endl;
cin >> choice;
// Encryption
if (choice == 1)
{
for (int i = 0; msg[i] != '\0'; i++) {
ch = msg[i];
//encrypt for lowercase letter
if(ch >= 'a' && ch <= 'z') {
ch = ch + shift;
if (ch > 'z') {
ch = ch - 'z' + 'a' - 1;
}
msg[i] = ch;
}
//encrypt for uppercase letter
else if (ch >= 'A' && ch <= 'Z') {
ch = ch + shift;
if (ch > 'Z') {
ch = ch - 'Z' + 'A' - 1;
}
msg[i] = ch;
}
}
printf("Encrypted message: %s", msg);
}
result
This is wrong because you need to use strcat too
// Read file into char array
ifstream infile("plaintext.txt");
while (getline(infile, plaintext))
{
strcpy_s(msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
}
Instead:
// Read file into char array
ifstream infile("plaintext.txt");
getline(infile, plaintext)
if (!plaintext.empty())
{
strcpy_s(msg, plaintext.c_str());
plaintext.clear();
while (getline(infile, plaintext))
{
strcat_s(msg, sizeof msg, plaintext.c_str());
for (int i = 0; i < plaintext.length(); i++)
{
cout << msg[i];
}
plaintext.clear();
}
}
I'm making a hangman game in C++ and I am close to finishing, however I have one major issue. I have to get the game to only allow the user 4 guesses, but my program doesn't register the correct number of guesses.
I've tried to change variables as well as the conditions within the if and else statements regarding guessing.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
cout << "Welcome to hangman!" << endl;
char choice = 'y';
while (choice == 'y') {
string word;
cout << "Enter a word to guess: ";
getline(cin, word);
if (word.empty()) {
cout << "The word should not be blank.\n";
continue;
}
bool contain_space = false;
for (char c : word) {
if (isspace(c)) {
contain_space = true;
break;
}
}
if (contain_space) {
cout << "The word cannot contain spaces.\n";
continue;
}
vector <bool> index;
for (int i = 0; i < word.size(); i++) {
index.push_back(false);
}
**int guess_correct = 0;**
int guess_wrong = 4;
char letter;
while (guess_wrong >= 0 && guess_correct < word.size()) {
bool valid_guess = true;
cout << "Guess a letter." << endl;
cin >> letter;
for (int i = 0;i < word.size(); i++) {
if (word[i] == letter) {
valid_guess = true;
index[i] = true;
guess_correct++;
break;
}
else {
guess_wrong = guess_wrong - 1;
}
}
for (int i = 0; i < word.size(); i++) {
if (index[i] == true) {
cout << word[i] << "\t";
}
else {
cout << "___\t";
}
}
cout << endl;
}
cout << "Would you like to play again? (y/n)" << endl;
cin >> choice;
cin.ignore();
}
return 0;
}
The black ticks show the beginning of the code section I'm stuck on. Each time I run it, it will let me go through the game with correct guesses, but incorrect guesses don't allow for 4.
You are decrementing guess_wrong for each letter in the word that doesn't match, not once for the "whole guess".
you probably want to move the guess_wrong = guess_wrong - 1; // aka guess_wrong-- out of the for loop and only do it if (!valid_guess).
This is my code for finding a palindrome of a string.
The initial execution works perfectly.
But when it comes to executing the program again, it goes to the label, and skips the cin statement and directly executes everything and finally reaches the end.
This didn't happen when I used it in c++ 6.0, but happens in visual studio 2015
Thanks in advance for your help.
#include "stdafx.h"
#include<iostream>
using namespace std;
void main()
{
char string[100], ch;
int x, i, j, flag = 0;
label:
cout << "Enter a string. Max Length 99 : ";
cin.getline(string, 100);
x = strlen(string);
cout << "Checking For Palindrome...........";
for (long i = 0; i < 5000000; ++i)
{
cout << "";
}
cout << endl;
for (i = 0, j = x - 1; i < x / 2; ++i, --j)
{
if (string[i] == string[j])
continue;
else
{
flag = 1;
break;
}
}
if (flag == 1)
cout << "The String You Entered Is Not A Palindrome";
else
cout << "The String You Entered Is A Palindrome";
cout << "\nDo you want to execute again? (Y/N)";
cin >> ch;
if (ch == 'y' || ch == 'Y')
goto label;
else
cout << "See You Later :)";
}
I'm currently trying to write code that takes user input as strings, and then convert them to integers if I need to. If the user decides to enter exit then the program should move on to calling a function. Here is what I have so far:
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
if (stoi(user_input) < 0 || stoi(user_input) > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
cin >> user_input;
}
else if (user_input == "exit"){
printArray(string_array, 10);
}
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
However, as I'm testing the program, the console is aborting the program if I enter exit. Is there a way for me to enter exit and then the program calls printArray?
I think this changes in your code will solve the problem. Please, try with this code:
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
if (user_input == "exit"){
printArray(string_array, 10);
}
else if (stoi(user_input) < 0 || stoi(user_input) > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
cin >> user_input;
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
}
}
Hope this helps
stoi doesn't accept non-numbers. Try this:
#include <iostream>
using namespace std;
void printArray(string string_array[], int size){
for (int i = 0; i < size; i++){
cout << string_array[i];
}
}
void a_func(){
string string_array[10];
string user_input;
while (user_input != "exit"){
cout << "Please enter a number between 0 - 100: ";
cin >> user_input;
//cout << "You have printed " << user_input << endl;
bool isNumber = true;
for(string::const_iterator k = user_input.begin(); k != user_input.end(); ++k) {
if (isdigit(*k) == false) {
isNumber = false;
break;
}
}
if (isNumber) {
int number = stoi(user_input);
if (number < 0 || number > 100){
cout << "Error, please re-enter the number between 0 - 100: ";
continue;
} else {
int array_index = stoi(user_input) / 10;
string_array[array_index] = "*";
}
} else if (user_input == "exit"){
printArray(string_array, 10);
break;
} else {
// Not a number and not "exit"; do nothing?
}
}
}
int main() {
a_func();
return 0;
}