Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
I found a code on the internet to encrypt user input with Caesar encryption. But in the code the loop head bother me, because we didn't have things like "message[i]" or "\0" in class. Is it possible to write this in a different way? But we had not used arrays as far as in this loop header. This is not homework or anything like that. I'm practicing for my computer science test next week and there will probably be something similar. The loop header always looked like this for example for(i = 0; i < 4; i++). How can I write this code without arrays?
How can I write the loop differently? Or do I have to change other code parts?
#include <iostream>
using namespace std;
int main()
{
char message[100], ch;
int i, key;
cout << "Enter a message to encrypt: ";
cin.getline(message, 100);
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;
return 0;
}
To have a for loop closer to what you are used to, we need to know how many letters were input. The smallest change that does that is to use strlen to count them.
for (i = 0; i < strlen(message); ++i)
However it's better to use std::string to hold text, because that knows it's size.
int main()
{
std::string message;
int key;
std::cout << "Enter a message to encrypt: ";
std::getline(std::cin, message);
std::cout << "Enter key: ";
std::cin >> key;
for (i = 0; i < message.size(); ++i)
{
char 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; //<-
}
}
std::cout << "Encrypted message: " << message;
return 0;
}
And even better than that, you can loop over the chars in a string directly
int main()
{
std::string message;
int key;
std::cout << "Enter a message to encrypt: ";
std::getline(std::cin, message);
std::cout << "Enter key: ";
std::cin >> key;
for (char & ch : message) // <- N.b. char &, we are modifying the `char` objects owned by message
{
if (ch >= 'a' && ch <= 'z')
{
ch = ch + key;
if (ch > 'z')
{
ch = ch - 'z' + 'a' - 1;
}
}
else if (ch >= 'A' && ch <= 'Z')
{
ch = ch + key;
if (ch > 'Z')
{
ch = ch - 'Z' + 'A' - 1;
}
}
}
std::cout << "Encrypted message: " << message;
return 0;
}
Look at this snippet. Sorry if I have made a mistake with syntax, but this is enough to give you a general idea.
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char message[100];
int key;
cout << "Enter a message to encrypt: ";
cin.getline(message, 100);
cout << "Enter key: ";
cin >> key;
encrypt(message, key);
cout << "Encrypted message: " << message;
return 0;
}
void encrypt(char& message, const int key) {
for (char& ch : message) {
if (islower (ch))
ch = encrypt (ch + key, 'a', 'z');
else if (isupper (message[i]))
ch = encrypt (ch + key, 'A', 'Z');
}
}
char encrypt(const char ch, const char lo, const char hi) {
return ch % hi ? lo + (chi % hi) : ch;
}
Related
I'm learning strings and am trying to write a cipher program where a user inputs a string, inputs the key(how many spaces to shift a number either left or right) and outputs the encrypted string. I believe I have it almost figured out, But I need help fixing the issue where spaces and special characters get changed as well as the letters. I believe it has something to do with the toupper function, but I can't be sure. Any help would be appreciated!
#include<iostream>
#include<string>
using namespace std;
int main() {
string message;
int key;
cout << "Your message? ";
getline(cin, message);
cout << "Encoding key? ";
cin >> key;
for (int i = 0; i < message.length(); i++) {
if (islower(message[i])) {
message[i]=toupper(message[i]);
}
if (message[i] >= 'A' && message[i] <= 'Z') {
message[i] += key;
}
if (message[i] > 'Z') {
int overLimit = message[i] - 'Z';
message[i] = 'A' + overLimit - 1;
}
else if (message[i]<'A') {
int underLimit = 'A' - message[i];
message[i] = 'Z' - underLimit + 1;
}
}
cout << message << endl;
return 0;
}
Your message[i] > 'Z' and message[i] < 'A' should be inside the first if, where you already have detected a letter. If it's outside, it's also changing any non-letter characters too! (for example, space ' ' passes message[i] < 'A' and gets changed)
Here's the fixed code, I just placed the ifs in the correct place
#include<iostream>
#include<string>
using namespace std; // This is bad, you should get used to writing std::cout
int main() {
string message;
int key;
cout << "Your message? ";
getline(cin, message);
cout << "Encoding key? ";
cin >> key;
for (int i = 0; i < message.length(); i++) {
if (islower(message[i])) {
message[i]=toupper(message[i]);
}
if (message[i] >= 'A' && message[i] <= 'Z') {
message[i] += key;
if (message[i] > 'Z') {
int overLimit = message[i] - 'Z';
message[i] = 'A' + overLimit - 1;
}
else if (message[i]<'A') {
int underLimit = 'A' - message[i];
message[i] = 'Z' - underLimit + 1;
}
}
}
cout << message << endl;
return 0;
}
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();
}
}
Write a program using for loop which stores alphabets from Z-A. Extract only vowels from this array and store them into another array vowels. Now display these vowels using for loop from vowels array.
My output is not working properly. If I write my name without spaces like abdulhananhamid, then it works and shows a u a a.
I do not know how to use cin in a for loop, either.
#include<iostream>
#include<conio.h>
using namespace std;
int vowel (char x);
int main()
{
char size=100;
char x[size];
char A[5];
int n,i,;
cout<<"Enter any string\n";
cin>>x;
for (i = 0, n = 0; i<size; i++)
if (vowel(x[i]))
A[n++] = x[i];
for (n = 0;n<5;n++)
cout << A[n] << " ";
getch();
return 0;
}
int vowel(char x)
{
if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
return 1;
else
return 0;
}
This looks like a good assignment for using std::string and std::getline.
std::string user_text;
std::cout << "Enter a string: ";
while (std::getline(std::cin, user_text)
{
const size_t length = user_text.length();
std::string vowels;
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels += c;
}
}
std::cout << "Vowels found: " << vowels << "\n";
std::cout << "\nEnter a string: ";
}
If you must use character arrays, you should check for overflow:
unsigned int MAXIMUM_CHARACTERS = 128;
char user_text[MAXIMUM_CHARACTERS];
char vowels_found[MAXIMUM_CHARACTERS];
std::cout << "Enter a string: ";
while (std::cin.getline(&user_text[0], MAXIMUM_CHARACTERS))
{
unsigned int vowel_index = 0U;
const size_t length = strlen(user_text);
for (size_t i = 0; i < length; ++i)
{
const char c = user_text[i];
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u'))
{
vowels_found[vowel_index++] = c;
}
}
vowels_found[vowel_index] = '\0';
std::cout << "Vowels found: " << vowels_found << "\n";
std::cout << "\nEnter a string: ";
}
A function for checking for a vowel could look like:
bool is_vowel(char c)
{
return (c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u');
}
I am using this program to implement Mono alphabetic cipher. The problem i am getting is when i input plain text it doesn't get out of the loop when condition is met which is pressing the enter key.Here is my code.
int main()
{
system("cls");
cout << "Enter the plain text you want to encrypt";
k = 0;
while(1)
{
ch = getche();
if(ch == '\n')
{
break; // here is the problem program not getting out of the loop
}
for(i = 0; i < 26; i++)
{
if(arr[i] == ch)
{
ch = key[i];
}
}
string[k] = ch;
k++;
}
for(i = 0;i < k; i++)
{
cout << string[i];
}
getch();
return 0;
}
Here the problem is probably the fact that getche() (unlike getchar()) just returns the first character when there are more then one inputed and you are on windows (othewise you wouldn't use cls) then the EOL is encoded with \r\n.
What happens is that getche() returns \r so your break is never actually executed. You should change it to getchar() even because getche is a non standard function.
You can even try to look for \r instead that \n in your situation but I guess the \n would remain in the buffer causing problems if you need to fetch any additional input later (not sure about it).
Relying on old C libraries in C++ is yucky. Consider this alternative:
#include <iostream>
#include <string>
using namespace std; // haters gonna hate
char transform(char c) // replace with whatever you have
{
if (c >= 'a' && c <= 'z') return ((c - 'a') + 13) % 26 + 'a';
else if (c >= 'A' && c <= 'Z') return ((c - 'A') + 13) % 26 + 'A';
else return c;
}
int main()
{
// system("cls"); // ideone doesn't like cls because it isnt windows
string outstring = "";
char ch;
cout << "Enter the plain text you want to encrypt: ";
while(1)
{
cin >> noskipws >> ch;
if(ch == '\n' || !cin) break;
cout << (int) ch << " ";
outstring.append(1, transform(ch));
}
cout << outstring << endl;
cin >> ch;
return 0;
}
I would do something like the fallowing which uses standard C++ I/O.
#include <iostream>
#include <string>
using namespace std;
// you will need to fill out this table.
char arr[] = {'Z', 'Y', 'X'};
char key[] = {'A', 'B', 'C'};
int main(int argc, _TCHAR* argv[])
{
string sInput;
char sOutput[128];
int k;
cout << "\n\nEnter the plain text you want to encrypt\n";
cin >> sInput;
for (k = 0; k < sInput.length(); k++) {
char ch = sInput[k];
for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
{
if(arr[i] == ch)
{
ch = key[i];
break;
}
}
sOutput[k] = ch;
}
sOutput[k] = 0;
cout << sOutput;
cout << "\n\nPause. Enter junk and press Enter to complete.\n";
cin >> sOutput[0];
return 0;
}