0

I'm relatively new to this site (and programming in general), so if this post is horrible like the last one, let me know if there's something I should change about it, and I'll try to do that.

So I'm given an array of 50 passwords in array Passwords, and my immediate challenge I'm facing is having to randomize their arrangement, with the help of a random number generator. For some reason, with the code I have, I'm making some mistake somewhere, resulting in the code being stuck in a loop or something. I know I'm close to being correct, but I just don't know where I made a mistake.

I tried to create a random number, check to see if it's already stated in array PasswordsTemp, and then: (if it is already in the array, do nothing), (if it isn't already in the loop, add it to the loop at the next available index). In order to then select another random number, this code has to loop. I set it to loop 600 times to (practically) ensure that it guesses every number 0 to 50 at some point. Following this, I just coded a simple cout for me to see what the array looks like.

Any help/advice would be appreciated. Just be aware that I'm relatively new here, so maybe try to go a little easy on me, or maybe just help someone else in lieu of berating me. Thanks.

#include <iostream>
#include <string>
#include <fstream>
#include <time.h>

int main()
{
std::string firstname = "";
std::string lastname = "";
std::string lastnametemp = "";
std::string fullname = "";
std::string Users[50] = {""};
std::string Passwords[50] = {""};
std::string NewPass = {""};
std::string temp = {""};
int PasswordsTemp[50] = {60};
int randomNumber = 0;
bool repeat = false;
int A = 0;
int i = 0;

std::ifstream inputHandler;
inputHandler.open("names.txt");

while (!inputHandler.eof())//ignore this part. I know it works.
{
    inputHandler >> firstname >> lastname; //reads first name and last name of one line
    lastnametemp = lastname.substr(0, 7); // sets temp last name as being at most, 7 letters long
    fullname = firstname[0] + lastnametemp; // combines the two into a full name
    Users[i] = fullname; //creates Users array
    i = i + 1;//indexes data
}


std::ifstream indata;
indata.open("passwords.txt");
i = 0;
    while (!indata.eof())
{
    indata >> Passwords[i];//reads in passwords into array called Passwords
    i = i + 1;
}
    inputHandler.close();


    //*******************************************************
    //****************Confusion hereafter********************
    //*******************************************************


    for (i = 0; i < 600; i++)//Loops a long time to (practically) ensure that all numbers 0 to 50 are guessed atleast once
    {
        srand(time(NULL));
        randomNumber = rand() % 51;//Produces random number between 0 and 50

        for (i = 0; i < 51; i++)
        {
            if (randomNumber == PasswordsTemp[i])
            {
                repeat = true;//determines if the random number appears anywhere in the PasswordsTemp array; repeat = true if it appears anywhere
            }
        }

        if (repeat == false)//if the random number doesn't appear anywhere, assign the random number an index in Passwordstemp
        {
            PasswordsTemp[A] = randomNumber;
            A = A + 1;
        }
    }
    //*****************************************************************************
    //**************************End of Confusion***********************************
    //*****************************************************************************
    for (A = 0; A < 51; A++)//Checks to see if the passwords are randomized
    {
        temp = Passwords[PasswordsTemp[A]];
        std::cout << temp << std::endl;
    }

return 0;
}
John Galt
  • 1
  • 1
  • `while (!inputHandler.eof())//ignore this part. I know it works.` [It doesn't work.](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Nov 24 '16 at 01:27
  • Neither does ` while (!indata.eof())` for the same reason. – user4581301 Nov 24 '16 at 01:27
  • @user4581301 I don't know what to tell you. Using my file names.txt, I am perfectly able to read in the two columns of text, and store them as variables first name and last name. Trust me, just ignore that part. I only have a problem with the part denoted by the asterisks.. – John Galt Nov 24 '16 at 01:33
  • Only call `srand(time(NULL));` once per program unless you have a really, really good reason to call it more often. Most definitely do NOT reset the seed before getting every random value. You will get the same value almost every time. – user4581301 Nov 24 '16 at 01:33

3 Answers3

0

May I suggest a different approach? Since you are running it 600 times, as you said, there is no guarantee that each number will be hit at least once. Instead, use a while loop that says: while PasswordsTemp contains randomNumber, randomize the randomNumber again:

while(PasswordsTemp.contains(randomNumber)
{
    randomNumber = rand() % 51;
}

then continue on with the lines already in your code:

PasswordsTemp[A] = randomNumber;
A = A + 1;

and put all of that in a for loop from 0 to the end of the PasswordsTemp length. Also, the length of PasswordsTemp is 50, not 51, so attempting to access PasswordsTemp[51] will return an error.

0

One simple way to produce your array of random passwords is to:

  1. Create an array containing 0 to 50.
  2. Apply std::random_shuffle or std::shuffle to the array. This will randomly reorder the elements.

All done.

special bonus edit:

while (!inputHandler.eof())//ignore this part. I know it works.
{
    inputHandler >> firstname >> lastname; //reads first name and last name of one line
    lastnametemp = lastname.substr(0, 7); // sets temp last name as being at most, 7 letters long
    fullname = firstname[0] + lastnametemp; // combines the two into a full name
    Users[i] = fullname; //creates Users array
    i = i + 1;//indexes data
}

Can't work. It tests for EOF before reading data from the file. You can't tell if you're reached the end of the file until after trying to read data and failing. Testing before you read ensures that you will read past the end of the file and use unread garbage. Always

  1. Read data
  2. Test that you read data
  3. Use the data or exit, depending on 2

So

while (inputHandler >> firstname >> lastname)// read and test
{
    // now use
    lastnametemp = lastname.substr(0, 7); // sets temp last name as being at most, 7 letters long
    fullname = firstname[0] + lastnametemp; // combines the two into a full name
    Users[i] = fullname; //creates Users array
    i = i + 1;//indexes data
}

Also recommend a limiter so you don't read too much data for the Users[i] array and using std::getline so you can catch names like "Victor Von Doom".

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • lol, I really appreciate your effort to help. I do. Just trust me that the EOF DOES store the first/last names. Here's some screenshots to show you. http://imgur.com/a/4sBkk – John Galt Nov 24 '16 at 01:58
  • @JohnGalt all the marker has to do to make your program screw up is put whitespace at the end of the input. [Add a blank line and typically you'll see the last name get repeated.](http://ideone.com/2O3qHQ) Leave a marker low hanging fruit and you're going to regret it, either in a low grade or a shoddy education. – user4581301 Nov 24 '16 at 05:35
-1

That is not being easy but you could store the first 50 the rng spat and sort them to map your list to it...

to be understand, here the pseudo-code of what i meant:

for(i=1..50) 
    a[i] <— rng
end for
for(i=1..50) 
    b[i] <— a[i]
end for

//not being easy
b <— sort(b)

for(i=1..50) 
    for(j=1..50) 
        if(b[i]==a[j]) shuffled_list[i] <— original_list[j]
    end for
end for
simonarame
  • 353
  • 2
  • 9