2016-04-05 18 views
-2

Ich habe die Caesar-Chiffre mit objektorientierter Programmierung implementiert. Das Problem ist, dass wenn ich die verschlüsselte Funktion anrufe, ich die gleiche Nachricht wie die Benutzereingabe bekomme ... Die Nachricht wird nicht richtig verschlüsselt.Caesar-Chiffre objektorientierte Programmierung

Zum Beispiel, wenn ich "abc" statt "bcd" schreibe, bekomme ich "abc". Ich habe es in C++ versucht, der Code funktionierte (die Logik war in Ordnung), aber ich versuchte objektorientiertes Programmieren in C++ und erstellte drei Dateien, um den Code zu trennen.

Kann mir jemand helfen oder einen Fehler identifizieren, den ich gemacht habe?

Executable Test File (main-Funktion):

#include <iostream> 
#include <string> 
#include "CyclicShift.h" 

using namespace std; 


int main() 
{ 

string text;//the string that holds the user input 

int key;//key holds the number by which the user wants the alphabets to be  shifted 

cout << "Enter your phrase: " << endl; 
getline(cin, text);//gets the user input (including spaces and saves it to the variable text) 

cout << "Please choose a number(key) for which you wants the alphabets to be shifted: " << endl; 
/*Note: the key can either be positive (forward shifting), negative (backward shifting) or zero (no shifting)*/ 

cin >> key;//User input for number by which alphabets are going to be shifted 

const CyclicShift aShift; 

cout << "Encrypted Message : " << aShift.Encrypt(text, key) << endl; 

//system("Pause"); 

return 0; 
} 

Header-Datei .h:

#pragma once 
#include <iostream> 
#include<string> 
//Note: No using "namespace std;" in header files 

class CyclicShift 
{ 
private: 

char fUpperCase[26];//A-Z 
char fLowerCase[26];//a-z 

public: 
CyclicShift(); 

std::string& Encrypt(std::string& aOriginalMessage, int &aKey) const;// Function Prototype. This declares Encrypt to be a function that needs one string and one integer variables as arguments. Reference operator & in prototype 

}; 

Quelldatei .cpp:

#include "CyclicShift.h" 
#include<iostream> 
#include<string> 

using namespace std; 

CyclicShift::CyclicShift() 
{ 
char fUpperCase[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'};//Initialization of class member 
char fLowerCase[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'};//Initialization of class member 

} 

string& CyclicShift::Encrypt(string& aOriginalMessage, int & aKey) const 
{ 

int z;//z holds the value (int) of the length of the user input (including spaces) 
z = (int)aOriginalMessage.length(); /*give the variable z the value of the user input length and length is normally an unsigned long integer hence 
          we have to typecast it*/ 

/*counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than z)*/ 
for (int i = 0; i < z; i++) 
{ 
    for (int j = 0; j < 26; j++) 
    { 
     if (aOriginalMessage[i] == fLowerCase[j] || aOriginalMessage[i] == fUpperCase[j]) 
     { 

      if (aKey > 0) 
      { 
       //another counter that loops forwards key times by incrementing method 
       for (int counter = 0; counter < aKey; counter++) 
       { 
        /*it checks if the letter text[x] is 'z' and if it is 'z' it will make it 'a'*/ 
        if (aOriginalMessage[i] == 'z') 
        { 
         aOriginalMessage[i] = 'a'; 
        } 

        else if (aOriginalMessage[i] == 'Z') 
        { 
         aOriginalMessage[i] = 'A'; 
        } 

        else 
        { 
         aOriginalMessage[i]++; 
        } 

       } 
      } 

      else if (aKey < 0) 
      { 
       //another counter that loops backwards key times by decrementing method 
       for (int counter = 0; counter < abs(aKey); counter++) 
       { 
        /*it checks if the letter text[x] is 'a' and if it is 'a' it will make it 'z'*/ 
        if (aOriginalMessage[i] == 'a') 
        { 
         aOriginalMessage[i] = 'z'; 
        } 

        else if (aOriginalMessage[i] == 'A') 
        { 
         aOriginalMessage[i] = 'Z'; 
        } 

        else 
        { 
         aOriginalMessage[i]--; 
        } 
       } 
      } 

      else 
      { 
       aOriginalMessage[i];//No alphabet shifts 
      } 

     } 

     else { 

      continue; 
      } 

     break; 
    } 

} 

return aOriginalMessage; 
} 

Oben sind die drei Code-Dateien von meinem Objekt -orientierte Implementierung: Test ing (main), Header und Quelldatei .cpp.

Antwort

2

Sie sollten fUpperCase und fLowerCase als static und initialisieren sie in der Header-Datei deklarieren. In Ihrem Code sind die Variablen, die Sie initialisiert haben, lokal für den Konstruktor, während die privaten Mitglieder unberührt bleiben.

EDIT

Wenn Sie sie in den Konstruktor zu initialisieren haben, na ja, können Sie etwas tun:

class CyclicShift 
{ 
    private: 

    char fUpperCase[26]; // A-Z 
    char fLowerCase[26]; // a-z 

    // ... etc. ... 
}  

CyclicShift::CyclicShift() 
{ 
    for (int i = 0; i < 26; ++i) { 
     fUpperCase[i] = 'A' + i; 
     fLowerCase[i] = 'a' + i; 
    } 
} 
+0

Thx sowieso aber laut meiner project the fUpperCase und fLowerCase sollten im Konstruktor initialisiert werden und die Vorlage sollte sie wie folgt deklarieren: char fUpperCase [26]; Daher kann ich es nicht statisch machen .... – Ketnav

+0

@Ketnav ok, nur sicher sein, sie nicht im Konstruktor neu zu deklarieren, nur initialisieren sie (nicht mit einer Initialisierungsliste). –

+0

Ich habe sie im Konstruktor neu deklariert :) aber das Ergebnis ist immer noch in Ordnung! – Ketnav

0

Ein Problem, das mir auffällt, ist, dass Sie das aktuelle Zeichen der Nachricht überprüfen

if (aOriginalMessage[i] == fLowerCase[j] || aOriginalMessage[i] == fUpperCase[j]) 

möglicherweise nachdem sie mit Ihrer Schicht geändert zu haben.

aOriginalMessage[i]++; 

da Sie über alle möglichen Zeichen iterieren. Möglicherweise möchten Sie die verschlüsselte Nachricht in einer anderen Variablen speichern.

Es könnte auch effizienter sein, das gesamte Alphabet zuerst zu verschieben und dann die verschobenen Zeichen für die verschlüsselte Nachricht direkt zuzuweisen.

Hoffe, dass hilft.

+0

Ich glaube nicht, dass das Problem ist ... wie ich sagte Ich habe die Logik in C++ unter einer Datei getestet und es funktioniert, wenn der Typ "abc" wird "bcd" aber es ist nur, wenn ich es in oop versuchte nicht funktioniert ... – Ketnav

0

Unten ist die C++ Code i getestet und ich wiederhole noch einmal seine beiden Arbeits zum Verschlüsseln und Entschlüsseln .... was bedeutet, die Logik in Ordnung ist ...

#include<iostream> 
#include<string> 

using namespace std; 

string Encrypt(string&, int &);// Function Prototype. This declares Encrypt to be a function that needs one variable as string and another as interger as arguments. Reference operator & in prototype 
string Decrypt(string&, int &);//Function Prototype. This declares Decrypt to be a function that needs one variable as string and another as interger as arguments. Reference operator & in prototype 

int main() 
{ 

string text;//the string that holds the user input 

int key;//key holds the number by which the user wants the alphabets to be shifted 

cout << "Enter your phrase: " << endl; 
getline(cin, text);//gets the user input (including spaces and saves it to the variable text) 

cout << "Please choose a number(key) for which you wants the alphabets to be shifted: " << endl; 
/*Note: the key can either be positive (forward shifting), negative (backward shifting) or zero (no shifting)*/ 

cin >> key;//User input for number by which alphabets are going to be shifted 

string kolo = Encrypt(text, key); 

cout << "Encrypted Message: " << kolo << endl;//Function call to display encrypted message 

//Decrypt(Encrypt(text, key), key); 

cout << "Decrypted Message: " << Decrypt(kolo, key)<< endl;//Function call to display decrypted message 

//system("Pause"); 

return 0; 
} 



string Encrypt(string& Source, int& c) 
{ 
char fUpperCase[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' };//Initialization of class member 
char fLowerCase[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' };//Initialization of class member 

int z;//z holds the value (int) of the length of the user input (including spaces) 
z = (int)Source.length(); /*give the variable z the value of the user input length and length is normally an unsigned long integer hence 
          we have to typecast it*/ 

/*counter that makes it keep looping until it "encrypts" all of the user input (that's why it keeps looping while its less than z)*/ 
for (int i = 0; i < z; i++) 
{ 
    for (int j = 0; j < 26; j++) 
    { 
     if (Source[i] == fLowerCase[j] || Source[i] == fUpperCase[j]) 
     { 
      //text[i] = fLowerCase[j]; 

      if (c > 0) 
      { 
       //another counter that loops forwards key times by incrementing method 
       for (int counter = 0; counter < c; counter++) 
       { 
        /*it checks if the letter text[x] is 'z' and if it is 'z' it will make it 'a'*/ 
        if (Source[i] == 'z') 
        { 
        Source[i] = 'a'; 
        } 

        else if (Source[i] == 'Z') 
        { 
        Source[i] = 'A'; 
        } 

        else 
        { 
        Source[i]++; 
        } 

       } 
      } 

      else if (c < 0) 
      { 
       //another counter that loops backwards key times by decrementing method 
       for (int counter = 0; counter < abs(c); counter++) 
       { 
        /*it checks if the letter text[x] is 'a' and if it is 'a' it will make it 'z'*/ 
        if (Source[i] == 'a') 
        { 
         Source[i] = 'z'; 
        } 

        else if (Source[i] == 'A') 
        { 
         Source[i] = 'Z'; 
        } 

        else 
        { 
         Source[i]--; 
        } 
       } 
      } 

      else 
      { 
       Source[i];//No alphabet shifts 
      } 

     } 

     else { 
       continue; 
      } 

     break; 
    } 

} 

return Source; 
} 

string Decrypt(string& EncryptedMessage, int& c) 
{ 
int y;//z holds the value (int) of the length of the user input (including spaces) 
y = (int)EncryptedMessage.length(); /*give the variable z the value of the user input length and length is normally an unsigned long integer hence 
          we have to typecast it*/ 


for (int i = 0; i < y; i++) 
{ 

    if (isalpha(EncryptedMessage[i]))//verify if the all members of the encrypted message is alphabet if not the same special character is return whereas if it is alphabet it is eitther incremented or decremented 
    { 

     if (c > 0) 
     { 
      //another counter that loops forwards key times by incrementing method 
      for (int counter = 0; counter < c; counter++) 
      { 
       /*it checks if the letter text[x] is 'a' and if it is 'z' it will make it 'a'*/ 
       if (EncryptedMessage[i] == 'a') 
       { 
        EncryptedMessage[i] = 'z'; 
       } 

       else if (EncryptedMessage[i] == 'A') 
       { 
        EncryptedMessage[i] = 'Z'; 
       } 

       else 
       { 
        EncryptedMessage[i]--; 
       } 

      } 
     } 

     else if (c < 0) 
     { 
      //another counter that loops backwards key times by decrementing method 
      for (int counter = 0; counter < abs(c); counter++) 
      { 
       //it checks if the letter text[x] is 'a' and if it is 'a' it will make it 'z' 
       if (EncryptedMessage[i] == 'z') 
       { 
        EncryptedMessage[i] = 'a'; 
       } 

       else if (EncryptedMessage[i] == 'Z') 
       { 
        EncryptedMessage[i] = 'A'; 
       } 

       else 
       { 
        EncryptedMessage[i]++; 
       } 
      } 
     } 

     else 
     { 
      EncryptedMessage[i];//No alphabet shifts 
     } 

    } 

    //cout << "Decrypted Message: " << EncryptedMessage << endl;//Function call to display decrypted message 


} 
return EncryptedMessage; 
} 
0

Ändern Sie den Konstruktor Code:

CyclicShift::CyclicShift() 
{ 
    static char const fUpper[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' };//Initialization of class member 
    static char const fLower[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' };//Initialization of class member 

    strcpy_s(fUpperCase, fUpper); 
    strcpy_s(fLowerCase, fLower); 
} 

Ich habe die Länge der Char-Arrays auf 27 geändert, um einen Pufferüberlauf zu vermeiden.

char fUpperCase[27];//A-Z 
char fLowerCase[27];//a-z 
+0

Hey gibt es noch andere können wir das tun .. Eigentlich ist es ein Projekt und es steht geschrieben, dass der Konstruktor den Fuppercase und den flowercase initialisieren soll ... Gibt es eine andere Möglichkeit, den fUpperC aufzurufen? ase und flowercase in der Verschlüsselungsmethode? – Ketnav

+0

Sie können 'strcpy' im Konstruktor verwenden wie' strcpy (fUpperCase, fUpper); ',' fUpperCase' ist die private Variable, die in Ihrer Kopfzeile definiert ist. Machen Sie dasselbe mit 'fLowerCase'. – abdul

+0

Hey Mann Ich kann strcpy nicht benutzen .... mein Compiler sagt "strcpy_s" !!! Ich versuchte strcpy_s (fUpperCase, 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); ... es kompiliert, aber ich bekomme eine Nachricht, die besagt ... Debug-Assertion ist fehlgeschlagen !!! @lucifer – Ketnav

Verwandte Themen