Runtime Error

Hi I'm new to C++ and working on a password protection program, I found the basic framework for a username/password online, and I edited it to encrypt the password, prompt for a password on first opening the program, and mask the password input with "*"s. When I type my password in too quickly, backspacing and pressing arrows, I receive the error "This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.". I'm almost positive it has something to do with the password masking, specifically the backspacing function. What can I do to fix it, as it always crashes the program? Thanks
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
#include<iostream>
#include<fstream>
#include<conio.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winable.h>
#include <cmath>
#include<string>
using namespace std;


void Auth(); //prompt to enter password
void Members(); //where you place your program, to be accessed after successful password
void First(); //prompt to enter a password if there isn't one on record (i.e first time opening program)
void menu(); //currently unused
void encrypt(string &e); //encrypt function
void decrypt (string &e); //decrypt function
string inpass;
string user;
string pass;
string first;
string firstconf;
int num = 0;
string com;
char c=' ';

main()
{
      system("cls");
      while(num==0)
      {
      system("cls");
      ifstream Passfile("password.txt", ios::in);
      Passfile>>inpass;
      if (inpass == ""){
      Passfile.close();
      cout<<"It appears that this is your first time opening this program\nplease enter a password: ";
      First();
      }
      
      Auth();
      
      cout<<"To access the program, type program, or to change your password, type password.\n";
      cin>>com;
    /*  if(com=="login")
      {
      Auth();
      }*/
      if(com=="password")
      {
           Passchange();
           }
      else if(com=="credits")
      {
           cout<<"written by ..."; 
           }
      else if(com=="exit")
      {
           cout<<"goodbye";
           getch();
           break;
           }
      else if(com=="program")
      {
           Members();
           }     
      else if(com==com)
      {
           cout<<"Unknown command\n";
           }
      }
}
void Auth()
{
     ifstream Passfile("password.txt", ios::in);
     Passfile>>inpass;
     decrypt ( inpass );
     system("cls");
     cout<<"PASSWORD: ";
     
         do   //Loop until 'Enter' is pressed
         {
            
         c = getch();
         switch(c)
            {
            case 0:
               {
               getch();     
               break;
               }
            case '\b':
               {
               if(pass.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  pass.erase(first.size() - 1, 1);
                  }
               break;       
               }  
              
            default:
            {
               if(isalnum(c) || ispunct(c))
                  {
                                      
                  pass += c;
                  cout << "*";           
                  }
                  else if(!isprint(c)){
                       getch();
                       }
               break;     
               }
            };
         }  
         
         
      while(c != '\r');
      
   cout<<"\n";
     Passfile.close();
     if(pass==inpass)
     {
     cout<<"\nSuccess! Hit enter to continue to program";
     getch();
     Members();
     }
     else
     {
         cout<<"Wrong Password, please try again.";
         getch();
         main();
         }
}

else
{
    cout<<"Invalid Password";
    getch();
    main();
}
}
  void First()
  {
       string first;
       string firstconf;
do   //Loop until 'Enter' is pressed
         {
         c = getch();
         switch(c)
            {
            case 0:
               {
               getch();
               break;
               }
            case '\b':
               {
               if(first.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  first.erase(first.size() - 1, 1);
                  }
               break;       
               }   
            default:
               {
               if(isalnum(c) || ispunct(c))
                  {
                  first += c;
                  cout << "*";           
                  }
                  else if(!isprint(c)){
                       getch();
                       }
               break;     
               }      
            };
         }
      while(c != '\r');
       cout<<"\n";
      system("cls");
      cout<<"Confirm Password: ";
     do   //Loop until 'Enter' is pressed
         {
         c = getch();
         switch(c)
            {
            case 0:
               {
               getch();
               break;
               }
            case '\b':
               {
               if(firstconf.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  firstconf.erase(first.size() - 1, 1);
                  }
               break;       
               }   
            default:
               {
               if(isalnum(c) || ispunct(c))
                  {
                  firstconf += c;
                  cout << "*";           
                  }
                  else if(!isprint(c)){
                       getch();
                       }
               break;     
               }
            };
         }  
      while(c != '\r');
   cout<<"\n";
     if (first.compare(firstconf) != 0){
       cout<<"Passwords do not match, please try again";
      Sleep(1000);
      system("cls");


      First();
}  
    else if(first.compare(firstconf) == 0) {
      ofstream Passfile("password.txt", ios::out);
      encrypt( first );
      Passfile<<first;
      Passfile.close();
      cout<<"Password successfully registered! You may now access the program";
      Sleep (1000);
      system ("cls");
      main();
      }
      }
void Members()
{
cout <<"Members area\n";
}

//encrypt data
void encrypt (string &e) 
{
  const char* tempCharArray = e.c_str();
  for( int i=0; i<e.size(); ++i )
    e[i] = tempCharArray[i]+75;

  
} // encrypt

//decrypt data
void decrypt (string &e)
{
  const char* tempCharArray = e.c_str();
  for( int i=0; i<e.size(); ++i )
    e[i] = tempCharArray[i]-75;
  
} // decrypt



Here is the code for the passcode masking alone, to make it easier to see.

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
 {
         c = getch();
         switch(c)
            {
            case 0:
               {
               getch();
               break;
               }
            case '\b':
               {
               if(first.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  first.erase(first.size() - 1, 1);
                  }
               break;       
               }   
            default:
               {
               if(isalnum(c) || ispunct(c))
                  {
                  first += c;
                  cout << "*";           
                  }
                  else if(!isprint(c)){
                       getch();
                       }
               break;     
               }      
            };
         }
      while(c != '\r');


Any help is appreciated. Thanks in advance
Hi,

You have some do loops, that look very similar, should these be made into a function? Then just call the function rather than write the same code over and over.

You have used global variables, which seems to be easy, but is bad form. It is better to pass pointers to functions.


DON'T CALL MAIN Control will return to where it was called from so this is completely unnecessary and really, really bad.



Hi,

My next order of business after solving the runtime error was to make those do loops into functions, and I'm still new and don't know what you mean by passing pointers to functions. Also, you told me never to call main, what should I call upon instead?

Thanks again
and don't know what you mean by passing pointers to functions.


OK so pass the variable itself to the function, it will be less efficient, but easier to understand. Read up on how to pass variable to functions and return them.

Also, you told me never to call main, what should I call upon instead?


read this bit again:

Control will return to where it was called from so this is completely unnecessary


Ok this is going to make me sound incredibly stupid and I am sorry, but when you say

Control will return to where it was called from so this is completely unnecessary


What is Control? I know that I most likely understand, I'm just really confused right now, sorry.
Control - flow is the order the computer executes the program. When you call a function, each line of code in the function is executed, then the program jumps back to where it was, and carries on from the line after the function call. So calling main to go back to the main program is pointless.

Control also jumps around obviously with loops, if else, switch etc.
Oh, right, of course, I've heard flow before but not control, thankyou very much. I just have to look into the backspace code and find out why it causes a crash.
1
2
3
4
5
6
7
8
9
 case '\b':
               {
               if(pass.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  pass.erase(first.size() - 1, 1);
                  }
               break;       
               }


This is the code for the backspacing, and I've gone over it a thousand times, and have found nothing wrong with it, yet my program still crashes the moment you hit the backspace button. This has got me properly stumped, is there anything wrong with this bit of code, or is it something else causing the crash?
Solved my problem, on this line:

pass.erase(first.size() - 1, 1);

it had pass.erase, followed by first.size, which is an entirely different thing, so it was opening the erase function for the string "pass", but then being told to resize the string "first", causing a crash, I simply changed first.size to pass.size, and it works like a charm.
One more slight problem. This code handles masking the password, including the now fixed backspace:

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
  do   //Loop until 'Enter' is pressed
         {
            
         c = getch();
         switch(c)
            {
            case 0:
               {
               getch();     
               break;
               }
            case '\b':
               {
               if(pass.size() != 0)  //If the password string contains data, erase last character
                  {
                  cout << "\b \b";
                  pass.erase(pass.size() - 1, 1);
                  }
               break;       
               }  
              
            default:
            {
               if(isalnum(c) || ispunct(c))
                  {
                                      
                  pass += c;
                  cout << "*";           
                  }
                  else if(!isprint(c)){
                       getch();
                       }
               break;     
               }
            };
         }  
         
         
      while(c != '\r');


The only problem I have is that you have to press enter twice to advance to the next screen, and I believe the problem lies here:

1
2
3
  else if(!isprint(c)){
                       getch();
                       }


This code ignores all non printable inputs (e.g. arrow keys, delete, f1 etc.), And I'm almost positive the problem stems from the getch(); line. Is there an alternative or a fix to this? Thanks
Once again, solved. Just removed the entire
1
2
3
else if(!isprint(c)){
                       getch();
                       }

and replaced it with
1
2
3
4
5
 case 0xE0: //Catches arrow keys, end, home, page up/down, etc.
                    {
                         getch();
                          break;
                          }

Which I placed directly under case 0: (line 7 of my previously posted code). Works perfectly now
Topic archived. No new replies allowed.