Home > Back-end >  How can I create dynamic array without asking user to enter a size in C ?
How can I create dynamic array without asking user to enter a size in C ?

Time:08-09

I want to take 8 char password from user and then when she/he wanted to enter, I wanted it to be whatever size she/he enter. However, the code doesn't stop until it reaches 8 char, even I press 'enter', it takes it as a char and create '*'. I want its size to be whatever user write and then user press 'enter', it will take these characters as password to see if it is matched with registered password. For example;

  • User register password as 'wellcode'
  • After that, user write in login screen 'well' then enter(in my code it lasts until I reach 8 characte
  • 'Login failed! will be written

Is there a way to do that in C ?

    bool CheckCredentials(string);
       char pass[8], inPass[8];
       int main()
        {
            fstream encrypted;
            bool done = false;
            while (!done)
            {
                cout << "1. Register a password" << endl;
                cout << "2. Login your password" << endl;
                cout << "3. Exit" << endl;
                
                int menuChoice;
                cin >> menuChoice;
        
                if (menuChoice == 1)
                {
                    
                    ifstream ifile;
                    ifile.open("password.txt");
                    if (ifile){}
                    else
                    {
                        cout << "New password must contain only 8 characters: ";
                        for (int i = 0; i < 8; i  )
                        {
                            pass[i] = _getch(); _putch('*');
                        }
                        ofstream l("password.txt", ios::out);
                        if (!l.is_open()) {
                            cout << "could not open file \n";
                        }
                        for (int i = 0; i < 8; i  )
                        {
                            l << pass[i];
                        }
                        l.close();
                        cout << "\n\n";
                    }
                }
        
                else if (menuChoice == 2)
                {
        
                        cout << "Password: ";
                        for (int i = 0; i < 8; i  )
                        {
                            inPass[i] = _getch(); _putch('*');
                        }
        
        
                        if (CheckCredentials(inPass) == true)
                        {
                            cout << "\nLogin sucessful!" << "\n\n";
                        }
                        else
                        {
                            cout << "\nLogin failed!"
                        }
        
                }
                else if (menuChoice == 3)
                {
                    done = true;
                    break;
                }
            }
        
            return 0;
        }

bool CheckCredentials(string inPass)
{
    string s;

    bool status = false;

    ifstream f;
    f.open("password.txt");

    if (!f.is_open())
    {
        cout << "Unable to open file!\n";
    }
    else if (f)
    {
        while (!f.eof())
        {
            f >> s;

            if (inPass == s)
            {
                status = true;
            }
            else
            {
                status = false;
            }
        }
    }

    f.close();
    return status;
}

CodePudding user response:

Your code is

for (int i = 0; i < 8; i  )
{
    inPass[i] = _getch();
    _putch('*');
}

Obviously that loops exactly eight times, doesn't matter what you type.

If you want to stop the loop early then you must write the code to test for that possibility. Something like

int inPassLength = 0;
for (int i = 0; i < 8; i  )
{
     char ch = _getch(); 
     if (ch == '\n')  // quit loop if enter is pressed
         break;
     inPass[inPassLength  ] = ch; 
     putch('*'); 
}

You also need to add a variable to record how long the password is (since it may not be exactly 8 characters any more) that's what inPassLength is in the code above.

CodePudding user response:

Your loop for (int i = 0; i < 8; i ) runs exactly eight times so you read exactly eight characters.

Instead you need to discover the user completing the password by pressing enter key and break the loop in that case. Additionally you need to consider the real number of characters the user entered, not again iterate exactly eight times to output the characters.

Then you haven't considered at all the user deleting input again! It would be pretty unhandy to see additional asterisks appear on pressing backspace key!

To cover all this I recommend using std::string instead and iterate endlessly, such as follows:

std::string pw;
for(;;)
{
    char c = getch();
    if(c == '\n')
    {
        break;
    }
    if(c == '\b')
    {
        putch('\b'); // remove character from screen
        pw.resize(pw.length() - 1); // remove character from storage
    }
    else
    {
        putch('*');
        pw  = c;
    }
}
if(pw.length() > 8)
{
    // too long!
}
else
{
    std::ofstream l /*...*/;

    l << pw; // just output the entire string at once...
}

Note: This is entirely untested code! If you find a bug, please fix yourself.

Note, too, that this answer does not cover every potential user behaviour (pressing backspace is just the most prominent one), e.g. pressing the arrow keys to move the cursor, del button (even at input end), ... To cover some of these you might fall back to even more low level API (GetKeyState and similar).

  • Related