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;
}
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;
}
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 am trying to remove the spaces from a string to validate a Palindrome phrase. I have looked up other methods, but my professor literally copy and pasted the remove space for loop in our instructions but I can't get it to work and he says he doesn't want us going to the internet for help. I am trying to remove spaces from a phrase like "too hot to hoot" to validate it. I can get my program to work with single words like "bob", but not phrases.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char input[100];
cout << "Please enter a word/phrase: ";
cin >> input;
for (int i = 0; i < strlen(input); i++)
{
while (s[i] == ' ')//getting "s" is undefined error
s.erase(i,1);
}
int i = 0;
int j = strlen(input)-1;
bool a = true;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if(a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout<< input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
Maybe you have not copy the result from temporary variable 's'. So, the modified codes should be:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
using namespace std;
int main(int argc, char *argv[])
{
char input[100];
cout << "Please enter a word/phrase: ";
fgets(input, 100, stdin);
string s(input); // define a temporary variable 's'
int i = 0;
while (i < s.length())
{
if (s[i] == ' ' || s[i] == '\n')
{
s.erase(i, 1); // erase from variable 's', other then 'input'
continue;
}
i++;
}
// copy result from 's' to 'input'
sprintf(input, "%s", s.c_str());
int j = strlen(input) - 1;
bool a = true;
i = 0;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if (a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout << input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
I would like to to print a triangle with a given letter. For example, if I input D, the program should return:
A
AB
ABC
ABCD
So far, I have managed to print all letters until the given one in my example, but as you see this method is not quite effective since I need to do this for all 26 cases since the English alphabet is 26 chars. Is there some way to optimize my code?
#include <iostream>
using namespace std;
int main() {
char i;
cout << "Enter char ";
cin >> i;
int c = static_cast<int>(i);
if (65 < c) {
cout << "A";
cout << endl;
}
if (66 < c) {
cout << "AB";
cout << endl;
}
if (67 < c) {
cout << "ABC";
cout << endl;
}
for (int i = 64; i < c; i++) {
cout << static_cast<char>(i + 1);
}
return 0;
}
You definitely need to work on your comprehension of loops. This one works just fine and it even has some checks on what is typed in and it eventually converts lower case letters into upper casse.
char first = 'A';
char last = 0;
cout << "Enter a char: ";
cin >> last;
fflush(stdin);
cout << "\n\n";
if ((last > 96) && (last < 123)) //97 to 122 are lower case letters
{
last -= 32; //32 is the delta between each lower case letter and its upper case "twin"
}
if ((last > 64) && (last < 91))
{
for (char i = 65; i <= last; i++)
{
for (char j = 65; j <= i; j++)
{
cout << j;
}
cout << "\n";
}
}
else
{
cout << "\nWrong character!!\n\n";
return 0;
}
Use a nested loop structure. Use the outer loop to 'walk' down your triangle,
lineLength = 1;
while(lineLength <= (c - 64)){
...stuff...
lineLength++;
cout << endl;
}
Use the inner loop to 'walk' down the alphabet (you've already done most of this):
for (int i = 0; i < lineLength; i++) {
cout << static_cast<char>(i + 65);
}
Putting it together:
lineLength = 1;
while(lineLength <= (c - 64)){
for (int i = 0; i < lineLength; i++) {
cout << static_cast<char>(i + 65);
}
lineLength++;
cout << endl;
}
I see that someone else has posted a similar answer. Between these two answers, you should be able to find your way. I haven't compiled and run this code, but I believe that it should work or be very close.
Don't harcode ascii integer values into code. Explicitly use the character or string literals (e.g. 'A' instead of 65)
Start with a helper function to print exactly one line
// prints all the characters of the alphabetic sequence from "A" to the final char designated by <c>
void printTriangleLine(char c)
{
if ((c < 'A') || (c > 'Z'))
{
return;
}
for (char x = 'A'; x <= c; x++)
{
cout << x;
}
cout << endl;
}
Then put it all together in your main:
int main()
{
char i;
cout << "Enter char ";
cin >> i;
if ((i < 'A') || (i > 'Z'))
{
return 0;
}
for (char x = 'A'; x <= i; x++)
{
printTriangleLine(x);
}
return 0;
}
We must run the loop from position is above 'A' character
until we reached the charanter you enter
// procead until reached input letter
while (chNew != c)
{
// go to next letter
chNew++;
// start with 'A' until current char + 1
for (int j = 'A'; j < chNew + 1; j++)
cout << (char)j;
// go to next line
cout << endl;
}
in each loop we increment character value by 1 to go to the next value
// go to next letter
chNew++;
inner loop simply print the character from A to next value relative to current chNew + 1, it is because we also want to include current character to our printed line.
Here is your working code.
#include <iostream>
using namespace std;
int main()
{
char i;
cout << "Enter char ";
cin >> i;
int c = static_cast<int>(i);
// start with 'A' - 1 character
char chNew = 'A' - 1;
// procead until reached input letter
while (chNew != c)
{
// go to next letter
chNew++;
// start with 'A' until current char + 1
for (int j = 'A'; j < chNew + 1; j++)
cout << (char)j;
// go to next line
cout << endl;
}
// we have done
return 0;
}
So, what I'm trying to do is, open and read a file, but read only the first line. I have already done this part. I have to read each character on that line and then I need to print the alphabet letters that are not found in that line.
Let's say the line was:
a b c D E f G H I j k L M n o
So, I will have to print the letters from p-z, because they are not in the line.
So, how will get the letters that are not in the line?!
This is what I have so far:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main(int argc, char *argv[]){
if(argc < 2){
cerr << "Usage: pangram <filename>" << endl;
return 0;
}
ifstream infile(argv[1]);
if (infile.good() == false){
cerr << "Error opening file[" << argv[1] << "]" << endl;
return 1;
}
char ch;
string line;
int a[26] = {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z};
int brk = 0;
while(infile.good()){
if(brk == 0) {
getline(infile, line);
for(int i=0; i <= line[i]; i++){
if(isalpha(line[i])) {
if(line[i] == )
cout << line[i] << endl;
}
}
}
brk ++;
if(brk == 1) {
break;
}
}
}
Here's a slightly modified version of your solution. I'm intentionally using a stack allocation of 26 bools instead of bitset so it's easier to comprehend.
bool letter_was_seen[26] = {}; // initialize an array to hold 26 bools (A..Z) all to false
getline(infile, line); // read a line into a string
size_t len = line.size();
for (size_t i = 0; i < len; i++)
{
char ch = ::toupper(line[i]); // convert to upper case
if ((line[i] >= 'A') && (line[i] <= 'Z')) // is it a valid letter A..Z ?
{
letter_was_seen[ch - 'A'] = true; // mark it's place in the array as "seen"
}
}
// now print the letters not seen within the line
for (char i = 'A'; i <= 'Z'; i++)
{
int index = (int)(i - 'A');
if (letter_was_seen[index] == false)
{
cout << i; // print the letter not seen
}
}
cout << endl; // print end of line to flush output
Another possible solution,
#include <deque>
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
deque<char> allChars(26);
iota(allChars.begin(), allChars.end(), 'a');
char readString[] = "test xyz";
for (char& c : readString) {
allChars.erase(remove(allChars.begin(), allChars.end(), c),
allChars.end());
}
cout<<"Not removed: ";
for (char& c : allChars) {
cout<<c<<" ";
}
cout<<endl;
}