c++ encryption with rotation - c++

I'm having some issues in creating a function that encrypts a word using a rotation number the user inputs. Here is what I have so far:
string encryptWord(string word, int num)
{
string newWord;
newWord = word;
for(int i = 0; i < word.length(); i++)
{
newWord[i] = tolower(word[i]);
if((word[i] >= 'a') && (word[i] <= 'z'))
{
newWord[i] = word[i] + (num % 26);
if(newWord[i] > 'z')
newWord[i] = newWord[i] - 26;
}
}
return newWord;
}
now in my main when I test it out with
cout << encryptWord("xyz", 6);
the output I get is: de
Similarly, for decryption I have
string decryptRotWord(string word, int num)
{
string newWord;
num = num % 26;
int index;
for(int i = 0; i < word[i]; i++)
{
newWord[i] = tolower(word[i]);
if(word[i] >= 'a' && word[i] <= 'z')
{
index = word[i] - num;
if(index < 'a')
index = index + 26;
newWord[i] = index;
}
}
return newWord;
}
however, for this one, it does not output anything when I test with
cout << decryptRotWord("vdds", 2);

In your decrypt function, I think you have a mistake on the loop end condition:
for(int i = 0; i < word[i]; i++)
As in the encrypt function, you should iterate over length
for(int i = 0; i < word.length(); i++)

When your for loop arrives to the letter 'z', it does 'z' + 6. But that goes beyond the max length of a char (127). You get an undefined behavior from that.
You should implement a way of starting to count from 'a' whenever you check the encryption goes beyond 'z'.
For the decryption, same as mentioned before, you want to test :
i < word.length()

Related

Why do I not need to use Input.Length[i]?

var input = Console.ReadLine();
int letterCount = 0;
int wordCount = 0;
int specialChar = 0;
for (int i = 0; i <= input.Length-1; i++)
{
if ((input[i] >= 'a'&& input[i] <= 'z' )|| (input[i] >= 'A' && input[i] <= 'Z'))
{
letterCount++;
}
else if (input[i] >='0'&&input[i]<='9')
{
wordCount++;
}
else
{
specialChar++;
}
}
(input[i] >= 'a'&& input[i] <= 'z' )|| (input[i] >= 'A' && input[i] <= 'Z') this is whats bugging me. Shouldn't I have to write input.Length[i] how does the program know that I am still using the input length ?
Your limitations defined in this loop, "i" will go from 0 to the length-1.
for (int i = 0; i <= input.Length-1; i++)
each time you enter the loop you will take input[0], input[1] and so on, that way you will iterate over all the input
Also Input.Length[i] in not valid.
Input.Length will return length
Input[I] will return the value in place "i" in the input.

Error for c++ example

I want to input alphabet to binary code, and output the alphabet from generated binary code.
Example
1 --> a
01 --> b
001 --> c
0001 --> d
00001 --> e
000001 --> f
a => 1
b => 01
c => 001
d => 0001
e => 00001
-------------Encode.cpp--------------------
#include "Encode.h"
Encode::Encode()
{
}
Encode::~Encode()
{
}
void Encode::inputWord()
{
cout << "Input word: ";
cin.getline(word, 255);
return;
}// User input a word
char * Encode::getBuf(void)
{
return buffer;
}// return buffer to Decode::setBuf(char* buf)
void Encode::printEncResult()
{
int size = strlen(word);
int buffersize = 0;
cout << "Encoding result" << endl; // print similar binary
for (int i = 0; i < size; i++)
{
if (word[i] == 'z')
{
for (int j = 0; j < 25; j++)
{
cout<<buffer[buffersize++];
}
}
else
{
int len = (int)word[i] - (int)'a';
for (int j = 0; j < len; j++)
{
cout<<buffer[buffersize++];
}
cout << buffer[buffersize++];
}
}
}// output similar binary
int Encode::encodeWord(void)
{
int buffersize = 0;
int size = strlen(word);
for (int i = 0; i < size; i++)
{
if (word[i] == 'z')
{
for (int j = 0; j < 25; j++)
{
buffer[buffersize++] = '0';
}
}
else
{
int len = (int)word[i] - (int)'a';
for (int j = 0; j < len; j++)
{
buffer[buffersize++] = '0';
}
buffer[buffersize++] = '1';
}
}
return 0;
}// change word to similar binary
--------Decode.cpp-------------
#include "Decode.h"
Decode::Decode()
{
}
Decode::~Decode()
{
}
void Decode::setBuf(char * buf)
{
int i = 0;
int size = 0;
while (*(buf + i) == '1' || *(buf + i) == '0')
{
i++;
}
size = i;
for(int i = 0; i < size; i++)
{
buffer[i] = buf[i];
}
return;
}// set buffer from Encode::getBuf(void)
void Decode::printWord() // print similar binary
{
int i = 0;
int size = 0;
int check = 1;
while (check)
{
if (word[i] >= 'a' && (int)word[i] <= 'z')
{
i++;
size = i;
}
else
check = 0;
}
cout << "Decoding result" << endl;
for (int i = 0; i < size; i++)
{
if (word[i] >= 'a' && (int)word[i] <= 'z') // **this part is also strange** I can not shoten the code.
cout<<word[i];
}
cout << endl;
}
int Decode::decodebin(vector<char> buffer)
{
int buffersize = 0;
int check = 0;
int size = 0;
int i = 0;
char printval = 'a';
while (buffer[i] == '1' || buffer[i] == '0')
{
i++;
}
size = i;
for (int j = 0; j < size; j++) // nested loop does not work. I want save words in order
{
for (i = 0; i < size; i++)
{
if (buffer[i] == '0')
++printval;
else
{
word[j] = printval; // In this part, word[0] does not have any value.
printval = 'a';
}
}
}
return 0;
}
In this code, I want save values in order, but word[0] does not have any value. Moreover, If I input 'bb' then, 'bbbb' saved ins word array.
There are some problems and consideration you need to take care of:
as Fei Xiang said in the comments don't use magic numbers, use characters since you have a character array.
int printWord function you actually get the word and print the same word, there is no conversion as your problem statement. your didn't take buffer into account.
you are using some data validation to get your array size, this could end up a disaster(UB). you need to pass your array size to your function or use std::vector(Recommended).
in this statement if ((int)word[i] >= 97 || (int)word[i] <= 122) as I said don't use magic number and || should be change to && otherwise you end up in an infinity loop.
Anyway by keeping your approach(using array) and function signature here's what you can do :
int Decode::decodebin(void)
{
int buffersize = 0;
int check = 0;
int size = 0;
int i = 0;
char printval = 'a';
while(buffer[i] == '1' || buffer[i] == '0')
{
i++;
size = i;
}
for(int i = 0; i < size; i++)
{
if(buffer[i] == '0')
++printval;
else
{
cout << printval;
printval = 'a';
}
}
return 0;
}
void Decode::printWord()
{
int i = 0;
int size = 0;
int check = 1;
while(check)
{
if(word[i] >= 'a' && word[i] <= 'z')
{
i++;
size = i;
}
else
check = 0;
}
cout << "Decoding result" << endl;
for(int i = 0; i < size; i++)
{
int distance = word[i] - 'a';
for(int j = 0; j < distance; ++j)
cout << '0';
cout << '1';
}
cout << endl;
}
EDIT BASED ON OP REQUIREMENT IN COMMENTS:
using std::vector you can implement your needs like this :
#include <iostream>
#include <vector>
class Decode
{
public:
void decodebin(std::vector<char> buffer)
{
char printval = 'a';
for(unsigned int i = 0; i < buffer.size(); i++)
{
if(buffer[i] == '0')
++printval;
else
{
word.push_back(printval);
printval = 'a';
}
}
}
void printWord(void)
{
for(auto iter = word.begin(); iter != word.end(); ++iter)
std::cout << *iter;
std::cout << std::endl;
}
private:
std::vector<char> word;
};
int main()
{
Decode decoder;
std::vector<char> buffer = {'0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '1'};
decoder.decodebin(buffer);
decoder.printWord();
return 0;
}
Here decodebin stores the given input into word member variable of Decode class. Then printWord function print word values on the screen.
std::vector has all the power of C-style array and it's nicer and easier to use. You can retrieve it's size whenever you want and you don't have to worry about the memory it's allocating.

continue not working? [c++]

Hi guys I've run into a problem,for some reason a blank string is being printed or you could also say nothing is being printed when I try to print out the string,this only occurs when I include a capital letter in the string such as acB if I type acb it sorts and prints them with no problems,I added a continue statement in to the for loop because I thought this would skip the rest of the code and go to the next iteration if that block of code got executed but to no avail anyway here is my code.
void order(char *str,int size){
bool sorted = false;
while(!sorted){
sorted = true;
for(int i = 0; i < size-1; i++){
if(str[i] >= 'A' && str[i] <= 'Z'){
if((str[i+1])-32 < str[i]){
char temp2 = str[i];
str[i] = str[i+1];
str[i+1] = temp2;
sorted = false;
continue;
}
}
if(str[i+1] < str[i]){
char temp = str[i];
str[i] = str[i+1];
str[i+1] = temp;
sorted = false;
}
}
}
}
int main()
{
char str[] = "aCb";
int size = sizeof(str) / sizeof(char);
order(str,size-1);
cout << str << endl;
}
void order(char *str,int size){
bool sorted = false;
while(!sorted){
sorted = true;
for(int i = 0; i < size - 1; i++){
if(str[i+1] >= 'A' && str[i+1] <= 'Z' && str[i] > 'Z'){
if(str[i+1] < str[i] - 32){
char temp2 = str[i];
str[i] = str[i+1];
str[i+1] = temp2;
sorted = false;
continue;
}
}
else{
if(str[i] >= 'A' && str[i] <= 'Z' && str[i + 1] >= 'Z'){
if(str[i+1] -32 < str[i]){
char temp2 = str[i];
str[i] = str[i+1];
str[i+1] = temp2;
sorted = false;
continue;
}
}
if(str[i+1] < str[i]){
char temp2 = str[i];
str[i] = str[i+1];
str[i+1] = temp2;
sorted = false;
continue;
}
}
}
}
}
int main()
{
char str[] = "aCB";
int size = sizeof(str) / sizeof(char);
order(str,size-1);
cout << str << endl;
}
First IF: Checks if the first letter is lowercase and the second letter is uppercase.
Second IF: Checks if the first letter is uppercase and the second letter is lowercase.
Third IF: then both letters are uppercase or lowercase.

Keep getting undeclared identifier I error caesar

I'm working on pset2 from the cs50 course, but I don't understand why I keep getting this error that I didn't declare I, because I think I did.. First I ask for a number to use as a key for the encrypting, than I ask for plain text, which should be encrypted by the number given, and printed out later.
Here's my code:
int main(int argc, string argv[])
{
// get key from command line argument, return 1 if wrong
if (argc < 2)
{
printf("No value entered!\n");
return 1;
}
//store key in integer
int k = atoi(argv[1]);
if (k < 0)
{
printf("No right variable detected\n");
return 1;
}
else
{
printf("Plain text: \n");
string s = get_string();
// iterate over strings in argv
for (int i = 0; n = strlen(s); i < n; i++);
{
if (isalpha(s[i]))
{
// for capitalized letters
if (isupper(s[i]))
{
int a = s[i] - 65;
int b = (a + k) % 26;
int c = b + 65;
printf("%c", c);
}
//for lowercase
else
{
int d = s[i] - 97;
int e = (d + k) % 26;
int f = e + 97;
printf("%c", f);
}
}
else
{
//for non alphabetical characters
printf("%c", s[i]);
}
}
}
// print new line
printf("\n");
return 0;
}
You have a ; at the end of for loop
for (int i = 0; n = strlen(s); i < n; i++);
^
Change it to
for (int i = 0, n = strlen(s); i < n; i++)
Moreover, as you can see init must be placed before the first semicolon ,(comma) separated.
Side notes
You should avoid to use "magic numbers" in code. In your case you can simply use
You should use variable names that can make your code more readable
You can do your ashing with a single variable, not 6
if (isalpha(s[i]))
{
int ashed;
// for capitalized letters
if (isupper(s[i]))
{
ashed = s[i] - 'A';
ashed = (ashed + k) % 26;
ashed += 'A';
}
//for lowercase
else
{
ashed = s[i] - 'a';
ashed = (ashed + k) % 26;
ashed += 'a';
}
printf("%c", ashed);
}
For loop is wrong, it accepts 3 parameters, you set it 4.
Also, notice semicolon after your for loop.
This line:
for (int i = 0; n = strlen(s); i < n; i++);
should be:
for (int i = 0, n = strlen(s); i < n; i++)
Notice comma and no semi-colon at the end

Converting a do-while loop into a while loop

My code is this I just want to convert my do-while loop into a for loop or a while loop how do I do that. The point of the program is to reverse the input word. like if you put in abc it would output as cba.
int main()
{
while (i < --length - 1);
cout << word << endl;
return 0;
}
The traditional way to convert a while loop into a for loop takes this form:
// While loop
int i = 0;
while( i < n ) {
// Amazing things happen here
i++;
}
// Equivalent for loop
for( int i = 0; i < n; i++ ) {
// Amazing things still happen here
}
Therefore, applied to your code it would look something like:
char ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
for( int i = 0, length = word.length(); i < --length - 1; i++ ) {
char ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
}
Note that since the do-while loop executes the body of the loop before testing, I had to put one copy of the loop body out front. To avoid having to update two different copies of the code, you may want to extract the loop body into a function, which is then called in front of the loop and in the loop body.
And for a while loop version:
int i = 0, length = word.length();
char ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
while( ++i < --length ) {
char ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
}
An alternative is this, which doesn't bother doing anything with strings of size 0 or 1:
int length = word.length();
if (length > 1)
{
int i = 0;
char ch;
while (i < length)
{
ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
i++;
length--;
}
}
For version:
int length = word.length();
if (length > 1)
{
char ch;
for(int i = 0; i < length; i++, length--)
{
ch = word[i];
word[i] = word[length - 1];
word[length - 1] = ch;
}
}