So I'm trying to learn loops and conditionals in c++ so i decided to write a program that generates a random password for the user. For some reason the code works maybe 1/5 times, but the rest of the time it just gives me "Exited With Non-Zero Status". Thanks, Evin
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <thread>
#include <time.h>
using namespace std;
int main()
{
using namespace std::this_thread;
using namespace std::chrono;
// Vars
string lett;
int input;
string password("");
string lettArray [] = {"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"};
// Prompt
cout << "How long would you like your password to be?";
cin >> input;
// Loop
for(int i = 0; i < input; i++)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
srand((time_t)ts.tv_nsec);
int random = (rand() % 26 + 1);
lett = lettArray[random];
password = password + lett;
sleep_for(milliseconds(10));
cout << "." << endl;
if (random == 0 )
break;
}
// Output
cout << password << endl;
return 0;
}
The reason that this program fails at random (pun intended) is that you are using C-arrays, and you got the index range wrong.
C-arrays, such as lettArray, do not check whether the array bounds are violated. In your example, if you run this program, lettArray[26]
will give you a segmentation fault because there is no string
element in that memory address. The C-array does not check the bounds, so it can be difficult to know what went wrong. This can get especially tricky in complicated programs because if something happens to be in that memory address you can get a nonsensical result.
A better implementation would be using std::vector
:
#include <iostream>
#include <cstdlib>
#include <chrono>
#include <thread>
#include <time.h>
#include <vector>
using namespace std;
int main()
{
// You don't need these two lines
//using namespace std::this_thread;
//using namespace std::chrono;
// Vars
string lett;
int input;
string password("");
// Vector index range: 0-25
vector<string> lettArray = {"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"};
// You only need to initialise the seed once.
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
srand((time_t)ts.tv_nsec);
// Prompt
cout << "How long would you like your password to be?";
cin >> input;
// Loop
for(int i = 0; i < input; i++)
{
int random = (rand() % 26 ); // You get results between 0-25
// Using lettArray.at(26) will result in a crash with a clear
// message that bounds are violated
lett = lettArray.at(random);
password = password + lett;
cout << "." << endl;
// Don't see a reason for this if statement
// if (random == 0 ){
// continue;
//}
}
// Output
cout << password << endl;
return 0;
}
I also moved the random seed outside the loop (you only need this once), and there is also no reason to have the 10 millisecond pause. You will see that your results are properly randomised regardless.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.