Encryption/decryption program cannot read string

I am currently working on a encryption/decryption machine for my programming class but I am having trouble. My program is suppose to be able to fetch a whole string using getline. Typing in a string results in the program hanging. Pressing Enter gets me to the program and am able to encrypt the string once. When the program repeats itself, entering the string again results in it not being stored and the encryption and decryption comes up blank. Here is my code if anyone can tell me what is wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#include<iostream>
#include<vector>
#include<set>
#include<string>

using namespace std;

class Substitution{
    int key;
    string input;
    bool encipher;
public:
    //constructor
    Substitution(string msg, bool enc):
        input(msg),encipher(enc){}
    
    //the function for encryption/decryption (Substitution algorithm)
    string substitution();
};

class Transposition{
    
    vector<char> letters;
    vector<int> indexes;
    
    // Key for Transposition
    string key;
    string input;
    bool encipher;
    
    // Encryption
    string encryptTransposition();
    // Decryption
    string decryptTransposition();
public:
    //constructor
    Transposition(string msg, bool enc):
    input(msg),encipher(enc){}
    
    //the function for encryption/decryption (Substitution algorithm)
    string transposition();
};

///////////////////////////////////////////////////////////////////////

//the function for encryption/decryption (Substitution algorithm)
string Substitution::substitution()
{
    
    do{
        cout<<"Enter key in 1..25>> ";
        cin>>key;
        //fflush(stdin);
        
        if(key>25 || key<1)
            cout<< "KEY ERROR";
        //check KEY: if encryption/decryption is possibly
        
    }while (key>25 || key<1);
    
    
    string output = "";
    
    
    for (int i = 0; i < input.size(); ++i)
    {
        if (isalpha(input[i])) //if letter
        {
            //offset='A' for upper letter, offset='a' for lowel letter
            char offset = isupper(input[i]) ? 'A' : 'a';
            
            //find shift for current letter for encryption (key) or for decryption (26 - key)
            int shift = encipher ? key: 26 - key;
            
            //convert letter (shift letter)
            char ch = (char)(((input[i] + shift - offset) % 26) + offset);
            output += ch;
        }
        else
        {
            //non letter
            output += input[i];
            
        }
    }
    
    return output;
}


//the function for encryption/decryption (Substitution algorithm)
string Transposition::transposition(){
    cout<<"Enter the word for the key>> ";
    cin>>key;
    set<char> symbols;
    
    //unique symbols
    for(char c:key)
        symbols.insert(c);
    
    int i=0;
    // Add the permutation order
    for(char c:symbols)
    {
        letters.push_back(c);
        indexes.push_back(i++);
        
    }
    
    if(encipher)
        return encryptTransposition();
    else
        return decryptTransposition();
}

// Encryption
string Transposition::encryptTransposition()
{
    
	int row, col;
	const int ROW = 26;
	const int COL = 50;
    string cipher = "";
    
    /* calculate column of the matrix*/
    col = int(letters.size());
    
    /* calculate Maximum row of the matrix*/
    row = int(input.length()/col);
    
    if (input.length() % col)
        row += 1;
    
    char matrix[ROW][COL];
    
    for (int i=0,k=0; i < row; i++)
    {
        for (int j=0; j<col; )
        {
            if(input[k] == '\0')
            {
                /* Adding the padding character '_' */
                matrix[i][j] = '_';
                j++;
            }
            
            if( isalpha(input[k]) || input[k]==' ')
            {
                /* Adding only space and alphabet into matrix*/
                matrix[i][j] = input[k];
                j++;
            }
            k++;
        }
    }
    
    for(auto j:indexes){
        // getting cipher text from matrix column wise using permuted key
        for (int i=0; i<row; i++)
        {
            if( isalpha(matrix[i][j]) || matrix[i][j]==' ' || matrix[i][j]=='_')
                cipher += matrix[i][j];
        }
    }
    
    
    return cipher;
}

// Decryption
string Transposition::decryptTransposition()
{
	const int ROW = 26;
	const int COL = 50;
    /* calculate row and column for cipher Matrix */
    int col = int(letters.size());
    
    int row = int(input.length()/col);
    char cipherMat[ROW][COL];
    
    /* add character into matrix column wise */
    for (int j=0,k=0; j<col; j++)
        for (int i=0; i<row; i++)
            cipherMat[i][j] = input[k++];
    
    /* update the order of key for decryption */
    int index = 0;
    for(auto& pos:indexes)
        pos= index++;
    
    /* Arrange the matrix column wise according
     to permutation order by adding into new matrix */
    char decCipher[ROW][COL];
    
    int k = 0;
    for (int l=0,j; l<letters.size(); k++)
    {
        j=indexes[l++];
        for (int i=0; i<row; i++)
        {
            decCipher[i][k]=cipherMat[i][j];
        }
    }
    
    /* getting Message using matrix */
    string msg = "";
    for (int i=0; i<row; i++)
    {
        for(int j=0; j<col; j++)
        {
            if(decCipher[i][j] != '_')
                msg += decCipher[i][j];
        }
    }
    return msg;
}


int main(){
    /*
     Encrypt a string entered by the user
     Choose between two different encryption methods
     Decrypt a string entered by the user
     Choose between two different decryptions methods
     Decrypt without knowing the encryption method (provide all possible outputs)
     */
    
    string source="";
    int option;
    
    
    do{
        
        cout<<"\nEnter the text>> "<<flush;
		getline(cin, source);
		cin.ignore(256, '\n');
		
        
        
        cout << "Make your choice"<<endl;
        cout << "\t1. Substitution cipher, encrypt"<<endl;
        cout << "\t2. Substitution cipher, decrypt"<<endl;
        cout << "\t3. Transposition cipher, encrypt"<<endl;
        cout << "\t4. Transposition cipher, decrypt"<<endl;
        cout << "\t5. Decrypt without knowing the encryption method (provide all possible outputs)"<<endl;
        cout << "\t6. Exit"<<endl;
        cout<<">> ";
        cin >> option;
       
        
        string result;
        
        switch(option){
            case 1:{
                Substitution s(source, true);
                result=s.substitution();
                cout<<endl<<"The encryption string:\n"<<result<<"\n";
                break;
            }
            case 2:{
                Substitution s(source, false);
                result=s.substitution();
                cout<<endl<<"The decryption string:\n"<<result<<"\n";
                break;
            }
            case 3:{
                Transposition t(source,true);
                result=t.transposition();
                cout<<endl<<"The decryption string:\n"<<result<<"\n";
                break;
            }
            case 4:{
                Transposition t(source,false);
                result=t.transposition();
                
                cout<<endl<<"The decryption string:\n"<<result<<"\n";
                break;
            }
                
            case 5:{
                Transposition t(source,false);
                result=t.transposition();
                cout<<endl<<"The decryption (transposition) string:\n"<<result<<"\n";
                
                Substitution s(source, false);
                result=s.substitution();
                cout<<endl<<"The decryption (substitution) string:\n"<<result<<"\n";
                break;
            }
                
            case 6:
                cout<<endl<<"Goodbye!"<<endl;
                break;
        }
    }while(option!=6);
    
    return 0;
}

Last edited on
Remove line 236 (the cin.ignore() statement)

Put it after line 248 (the cin >> statement)
Last edited on
That seemed to help with the hanging part but the getline doesn't seem to want to prompt me again for the text when the program loops, after it shows the encryption string, it should prompt the user to enter the text again so the program can decrypt it. It seems to want to skip over it as seen in the output below after the encryption string. Any ideas?
Enter the text>> this is a test
Make your choice
        1. Substitution cipher, encrypt
        2. Substitution cipher, decrypt
        3. Transposition cipher, encrypt
        4. Transposition cipher, decrypt
        5. Decrypt without knowing the encryption method (provide all possible outputs)
        6. Exit
>> 1
Enter key in 1..25>> 8

The encryption string:
bpqa qa i bmab

Enter the text>> Make your choice
        1. Substitution cipher, encrypt
        2. Substitution cipher, decrypt
        3. Transposition cipher, encrypt
        4. Transposition cipher, decrypt
        5. Decrypt without knowing the encryption method (provide all possible outputs)
        6. Exit
>> 2
Enter key in 1..25>> 8

The decryption string:


Enter the text>> Make your choice
        1. Substitution cipher, encrypt
        2. Substitution cipher, decrypt
        3. Transposition cipher, encrypt
        4. Transposition cipher, decrypt
        5. Decrypt without knowing the encryption method (provide all possible outputs)
        6. Exit
>>
Last edited on
You need another cin.ignore after all the other cin>> statements (lines 52 and 94).

The problem is that the extraction operator >> leaves a newline ('\n') in the stream, whereas getline(cin, std::string) removes it.



After adding the cin.ignores in the other lines, my program now works perfectly! Thank you for your help.
Topic archived. No new replies allowed.