-1

I am setting up a sign up, and login program, but it never allows to login. At the time of execution, it displays entering two characters while the user types only one, and also at the time of login the password never matches. Any solutions for goto.

#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
int i, t = 3;
struct dateob {
int day;
int month;
int year;
};
struct userdetails {
char name[50];
dateob dob;
char country[100];
char residential_address[100];
char office_address[100];
char citizen_proof[100];
long phoneno;
char gender[10];
long money;
char username[100];
char password[100];
 };
userdetails ud[3];

char u[100], u1[100];

void Entering(char a, int n)
{
    if (a == 'S')
    {
        cout << "Username ";
        cin.ignore();
        cin.getline(ud[n].username, 100);
        string user = ud[n].username;
        cout << "Password ";
        for (i = 0; i < 100; i++)
        {
            ud[n].password[i] = _getch();
            if (ud[n].password[i] == 13)
                break;
            cout << "*";
        }
        cout << "\n"
             << "User Created\n";
        goto login;
    }
    else if (a == 'L')
    {
    login:
        char username[100], password[100];
        cout << "Welcome To Login";
        for (int j = 0; j <= 3; j++)
        {
            cout << "Username ";
            cin.ignore();
            cin.getline(username, 100);
            cout << "Password ";
            for (i = 0; i < 100; i++)
            {
                password[i] = _getch();
                if (password[i] == 13)
                    break;
                cout << "*";
            }
            if (strcmp(username, ud[n].username) == 0 && strcmp(password, ud[n].password) == 0)
            {
                cout << "You can Enter :)";
                break;
            }
            else
            {
                cout << "\nSomething went wrong! \n";
                cout << "You Left with" << t-- << "Try \n";
            }
        }
        if (t == 0)
            cout << "You are Suspicious";
    }
}
int main()
{
char a, b, c;
int d;
for (int n = 0; n < 3; n++)
{
    cout << "Do you want to enter users :Y/N ";
    cin >> b;
    if (b == 'Y')
    {
        cout << "Sign Up : S \n"
            << "Login : L \n";
        cin >> a;
        Entering(a, n);
    }
    else
        break;
}
return 0;
}

I entered only 2 characters from keyboard but it displays 4 characters.You can see screenshot of result here I expected that it takes the password, and store it, and then can be used as an reference for Login.

Mrigank Sharma
  • 1
  • 1
  • 1
  • 3
  • 1
    After pasting code in, highlight it all and press the `{ }` button, to prefix every line with 4 spaces (code block) – Caius Jard Apr 18 '19 at 15:52
  • 1
    Please post a [Minimal Complete Verifiable Example](https://stackoverflow.com/help/mcve). It means code just sufficient to produce what you error you are getting. – Nevus Apr 18 '19 at 15:56
  • 1
    Oof [please don't use `goto`.](https://xkcd.com/292/) The cases in 2019 C++ code where `goto` may be necessary are few and far between. And this is not one of them. – scohe001 Apr 18 '19 at 16:05
  • 2
    `goto login;` -- Please don't do this. – PaulMcKenzie Apr 18 '19 at 16:05
  • 4
    `double phoneno;` is going to be fun ... – Ted Lyngmo Apr 18 '19 at 16:10
  • `getline` consumes the end of line, so placing an `ignore` between two `getline`s is probably going to result in discarding a character you don't want discarded. – user4581301 Apr 18 '19 at 16:39
  • 1
    If `getch()` returns a backspace, appending it to the password and increasing the buffer length used (`i`) is going to be very surprising to the user. – Ben Voigt Apr 18 '19 at 16:54
  • 2
    An important note on producing a [mcve] you need Minimal, Complete and Verifiable. Previously the question lacked Minimal (still does, technically), but now it also lacks Complete and Verifiable. We cannot compile and run the given code (Complete) to see the error (Verifiable). This means that any answer we give may not be correct because we cannot test them. That said, the real reason we want a MCVE is MCVE is a powerful debugging technique. Applying it will very often reveal the cause of the bug to you and eliminate the need to ask the question. – user4581301 Apr 18 '19 at 16:58
  • I made some changes, please check. – Mrigank Sharma Apr 18 '19 at 17:42

1 Answers1

2

Welcome to SO, Mrigank.

There are several things wrong with this code, I'd like to help you with some pointers if that's okay. Lots of these things are already in the comments.

First, instead of goto, which has lots of problems, use a loop:

bool loginSuccessful = false;
while (!loginSuccessful) {
    // Do the login stuff here
}

Second, the phone number really should be a string (looking like you'd probably want to use char[15] or something) in your struct at the top. the double type can be volatile and messy and should really only be used for math and such.

Third, and to answer your question, most terminals in most operating systems echo characters to the console as they're being input into standard in (cin). Differnt OSes let you turn this off in different ways. To quote this post:

In Windows, you can turn off echo for any standard input function with SetConsoleMode().

#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

int main()
{
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); 
    DWORD mode = 0;
    GetConsoleMode(hStdin, &mode);
    SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));

    string s;
    getline(cin, s);

    cout << s << endl;
    return 0;
}//main

In *nix you can use the "termios" interface to disable echo.

#include <iostream>
#include <string>
#include <termios.h>
#include <unistd.h>

using namespace std;

int main()
{
    termios oldt;
    tcgetattr(STDIN_FILENO, &oldt);
    termios newt = oldt;
    newt.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);

    string s;
    getline(cin, s);

    cout << s << endl;
    return 0;
}//main

You can probably also get a lot of ideas for how to solve this in different ways if the above doesn't work by consulting this SO question.

Finally, your cin calls should probably be completely changed. I have never used ignore() before in this context and it looks odd to me, I don't think it will help you. You are getting up to 100 characters per line (getline(..., 100)) but you should only be getting 99 characters, so as to leave one character for the null terminator. (This is a byte with a value of 0 that says "the string is terminated, or done".)

Rather than doing a getline, you may just use the >> operator on cin, or better yet, have a look at how the people in the SO answer above and in the forum post are getting input.

Hope this helps.

Community
  • 1
  • 1
djhaskin987
  • 9,741
  • 4
  • 50
  • 86