Sign in to follow this  
Dakar

Encryption program problem

Recommended Posts

I've recently learnt inheritence, and I've built an encryption program using it.
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class cipher
{
 protected:
  char *sent; // The encrypted/non encrypted sentence
 public:
  char *define_sent();
};

char *cipher::define_sent()
{
  cout << "Enter a sentence to encrypt, or an encrypted sentence to decrypt: ";
  gets(sent);
  return sent;
}  
  
class encrypt : public cipher
{
 public:
  void change_sent(); //to encrypt
};

void encrypt::change_sent()
{
  int i = strlen(sent);
  sent[i + 1] = '\0';
  for (int i = 0; sent[i]; i++) sent[i]++;
  cout << "\n\nYour (horrible) encryption program makes it:\n\n";
  for (int i = 0; sent[i]; i++) 
   {
    cout << sent[i];
   }
}

class decrypt : public cipher
{
 public:
  void change_sent(); //to decrypt
};

void decrypt::change_sent()
{
  int i = strlen(sent);
  sent[i + 1] = '\0';
  for (int i = 0; sent[i]; i++) sent[i]--;
  cout << "\n\nYour decryption program makes it:\n\n";
  for (int i = 0; sent[i]; i++) 
   {
    cout << sent[i];
   }   
}

int main (int argc, char *argv[])
{
  char choice;

  cout << "E.ncrypt or D.ecrypt?";
  cin >> choice;


   
  if (choice = 'E' || 'e') 
   {
    encrypt waka;
    waka.define_sent();
 //   waka.change_sent();
   } 
  else if (choice = 'd' || 'D')
   {
    decrypt waka; //was same name to make it easier to write code
    waka.define_sent();
    waka.change_sent();
   } 
  else cout << "That was not E or D! game over.";

          
  system("PAUSE");
  return 0;
}


Problem is that after entering E or D, the program does define_sent, returns it before any sentences can be typed, then does change_sent with the blank sentence. Any help? Thanks, ~Dakar [Edited by - Dakar on August 18, 2004 11:05:32 AM]

Share this post


Link to post
Share on other sites
I changed it. Nothing happened.

I think the problem is in the <gets(sent);> line. Changing it to <cin >> sent;> makes it work properly (but only allow one word to encrypt). Also note that no matter what letter you enter, it will only encrypt.

I rewrote a section of the code so that the choice problem won't happen, but I still have the <gets(sent);> problem.

#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class cipher
{
protected:
char *sent; // The encrypted/non encrypted sentence
public:
char *define_sent();
};

char *cipher::define_sent()
{
cout << "Enter a sentence to encrypt, or an encrypted sentence to decrypt: ";
gets(sent);
return sent;
}

class coder : public cipher
{
public:
void change_sent(); //to encrypt
void decryption();
};

void coder::change_sent()
{
int i = strlen(sent);
sent[i + 1] = '\0';
for (int i = 0; sent[i]; i++) sent[i]++;
cout << "\n\nYour (horrible) encryption program makes it:\n\n";
for (int i = 0; sent[i]; i++)
{
cout << sent[i];
}
}

//class decrypt : public cipher
//{
// public:
//to decrypt
//};

void coder::decryption()
{
int i = strlen(sent);
sent[i + 1] = '\0';
for (int i = 0; sent[i]; i++) sent[i]--;
cout << "\n\nYour decryption program makes it:\n\n";
for (int i = 0; sent[i]; i++)
{
cout << sent[i];
}
}

int main (int argc, char *argv[])
{
char choice;
coder waka;

cout << "E.ncrypt or D.ecrypt?";
cin >> choice;


switch(choice)
{
case 'E':
waka.define_sent();
waka.change_sent();
break;
case 'D':
waka.define_sent();
waka.decryption();
break;
default: cout << "That was not E or D! Game over.";
}

/* if (choice == 'E' || 'e')
{
encrypt waka;
waka.define_sent();
// waka.change_sent();
}
else if (choice == 'd' || 'D')
{
decrypt waka; //was same name to make it easier to write code
waka.define_sent();
waka.change_sent();
}
else cout << "That was not E or D! game over.";*/



system("PAUSE");
return 0;
}


Share this post


Link to post
Share on other sites
"gets" stores the returned text in a buffer, which needs to be pre-allocated. As it stands, I think it is just overwriting random memory segments. either define sent[MaxLength] or dynamically allocate it first.

Then, "gets" does no length checking, so you get to enter the fun fun world of buffer overflows. You may want to use "fgets" instead.

if you use cin >> whatever, you will only get to the first whitespace character, hence 1 word. you can use cin.getline ()

define_sent returns sent, which is weird because sent is a member variable. maybe just make it a void function.

the line:
sent[i + 1] = '\0';
is redundant, the null char is what strlen looks for.

maybe those will help...I'm not sure why it is only doing encryption, but some errors may resolve themselves.

hope it helps.

Share this post


Link to post
Share on other sites
Flush the buffer after the cin but before the gets
like so: cin.ignore(5,'\n');

gets is like getline, it reads until the newline character '\n' which is essentially the enter key.
cin leaves '\n' in the buffer so the first character gets encounters is the one that tells it to stop reading

Share this post


Link to post
Share on other sites
Lonesock: I've just tried everything you've said. Making it an array does not help, neither does fgets or cin.get(). It keeps on simply displaying the sentence request and moving on.

v0dKA: I've made it so that it allocates memory. No change.

Matt Apple: Well, changing 5 to 0 in <cin.ignore(5, '\n') makes the program work! (I've also found a couple other ways to make it work) I'd like to ask a few questions based on that.

What exactly does gets() do? The book I'm using says its like cin.getline, but then why wouldn't it allow me to give input?

I've checked, and removing <cin.ignore> and keeping both gets() and
cin.getline() makes it work fine. Also including the line and changing cin.getline to cin also makes it work, though the first letter is cut off. How does each scenario work?

Is the any way to allow an infinite sized string? While in <cin.get(array, int) I can make int a large number, is there any way so that int can never be exceeded?

Thanks,

~Dakar

Share this post


Link to post
Share on other sites
The following example may give you some hint as to how to enable arbitrary sized string input.


#include<iostream>
#include<string>
using namespace std;

int main(int argc, char* argv[])
{
cout << "Enter a string of any length: ";
basic_stringstream<char> s;

char c;
do
{
cin.get(c);
if(c=='\n')
break;
s << c;

}while(1);
cout << s.str() << '\n';
return 0;
}





You could make it even simpler and allow multi-line input if you are content with entering ctrl-Z on an empty line to signal the end of the input.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this