Reputation:
Here is what I should do making a program that reads a text file that contains encrypted message and crack it it is kind of close to substitution cipher where I should swap swap each letter back with another meaning like shifting B back to A if its being shifted by one, and try comparing shifted words by some common used words to find if 2 of the common words have been found on the shifted ones
ex: shift the word by one
check when you shifted it is there 2 common words found?
no keep going
yes means thats it stop shifting
Now this issue here which makes the program hard for me is that I do not have a key to be entered it would've been awesome if I had it.
3 issues I am having now, is in my void function it will not print anything, the second issue is, even if I fix my issue (I know this because in my function I have added something to convert string to c_string) and the issue is it will not shift until it finds the words I am looking which I have declared in string "Common[]" 3rd issue is whenever I compile I get an error invalid conversion from const char** to char comparison between signed and unsigned integer expressions
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;
void makeshift (string encrypt, int key)
{
for (int i = 0 ; i<encrypt.size();i++)
{
cout<<encrypt<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[])
{
// this will make me compare between encrypted message to check if it
// contains this words or not!
const char* common[]{"the","and","in","he","with","that","as","at","do"};
string encrypted; // The encrypted message gotten from file
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
///loop throgh it to store numbers in declared varibles
for (int i = 0 ; i < encrypted.size();i++)
{
makeshift(encrypted,i);
// here is where the error occurs which is "invalid conversion
// from const char to char
if(encrypted.find(common) != -1)
{
cout<<"found common"<<endl;
cout<<encrypted<<endl;
break;
}
}
}
}
}
Upvotes: 0
Views: 2093
Reputation: 361605
First, you say you're getting a compile error on this line:
if(encrypted.find(common) != -1)
The reason for that is because find()
expects its argument to be a string, but common
is an array of strings. In other words, find()
can only search for one word at a time. It can't search for a whole list of words.
To fix that, you'll want to write a loop and check one word each iteration.
Next up is the makeshift
function. A couple of suggestions there.
c_str()
. You can change encrypted
directly by modifying each encrypted[i]
in the loop.encrypted
but do not return it then the caller won't see the result.Here's what it looks like with those issues addressed:
string makeshift (string encrypt, int key)
{
cout << encrypt << endl; // to see what is in file way to debug
for (int i = 0 ; i<encrypt.size();i++)
{
encrypted[i] -= key;
}
cout << "decrypted message is " << encryptedc << endl;
return encrypted;
}
And then you would call it as:
string decrypted = makeshift(encrypted, i);
By the way, I'm not sure if the encrypted[i] -= key;
line is completely correct. My guess is you'll need to handle wraparound. Like if you subtract 3 from the letter "A" you should probably wrap around to "X", correct? If so, I'll leave that as a TODO for you.
Lastly, let's talk about I/O. Specifically, this bit of code:
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
...
}
}
A good practice in C++ is to check the results of I/O operations (e.g. getline). After you read a line you need to check that the read actually worked. You don't want to continue on if getline()
failed (say, because it hit end-of-file).
Conveniently, if you write while (getline(...))
then that'll do a whole bunch of things all at once--it'll check if the file is open, if it's at EOF, and it'll read lines and tell you if the reads were successful. That means you can replace the stuff above with a single loop:
ifstream message(argv[1]); // get file name typed by user
while (getline(message, encrypted))
{
...
}
Upvotes: 1
Reputation: 129
You are passing the value of encrypted to makeshift, so whatever you do in makeshift function will not change the encrypted in main function you have 2 solutions here:
you can either pass the pointer of encrypted to the makeshift function
void makeshift (string* encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt->c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt->c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[]){
...
makeshift(&encrypted, i);
...
}
Or you can return the value of encryptedc and assign it back to encrypted in main function
string makeshift (string encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt.c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
return encryptedc; //you can assign const char* to string
}
}
int main (int argc, char* argv[]){
...
encrypted = makeshift(encrypted, i);
...
}
Upvotes: 0