seihyung Ответов: 1

У меня возникла проблема с реализацией функции входа в мою программу....


Дорогие ребята,

Я пишу код, который проверяет идентификатор и пароль из обычного текстового файла(user.txt)

я хотел, чтобы программа проверяла идентификатор после того, как я набрал его, прочитав данные из user.txt но у меня была проблема.

пример:

Идентификатор: Луи
pwd:Ленокс

неверный идентификатор!

эти id и pwd наверняка находятся внутри user.txt но моя программа не могла его прочитать.
Я покажу вам свой код, и кто-нибудь подберет ошибку в моем коде, чтобы исправить ее, я был бы вам очень признателен.
- заголовочный файл -


#pragma once
#define _CRT_SECURE_NO_WARNINGS
#ifndef COMMON_H
#define COMMON_H

#include <iostream>
#include <memory>
#include <fstream>
#include <string>
#include <iomanip>
#include <conio.h>

using namespace std;
const char* userDB = "user.txt";//contains user info
const char* recordDB = "record.txt";//contains game record
const char* help = "help.txt";

#define MAXLENGTH    8
#define MAXNUM       3
#define MAXTRIALS    3

struct loginfo
{
	string id;
	string pwd;
	friend istream &operator >> (istream& is, loginfo l)
	{
		return is >> l.id >> l.pwd;
	}
};
//password masking
string setpass(const char* prompt, bool show_asterisk = true)
{
	const char BACKSPACE = 8;
	const char RETURN = 13;
	string pass;
	unsigned char c = 0;
	cout << prompt;

	while ((c = _getch()) != RETURN)
	{
		if (c == BACKSPACE)
		{
			if (pass.length() != 0)
			{
				if (show_asterisk)
					cout << "\b \b";
				pass.resize(pass.length() - 1);
			}
			else if (c == 0 || c == 224)
			{
				_getch();
				continue;
			}
		}
		else
		{
			pass.push_back(c);
			cout << '*';
		}
	}
	cout << endl;
	return pass;
}
//check whether userDB file exist or not
bool isExist(const char* f)
{
	fstream in;
	in.open(f, ios::in | ios::binary);

	if (in.fail())
		return true;
	else
		return false;
}
//check continue signup or not
bool isContinue()
{
	char m;
	cout << "Continue?(Yes = y,No = n)";
	cin >> m;
	if (m == 'y')
		return true;
	else if (m == 'n')
		return false;
}
//main menu screen
int mainMenu()
{
	int ch;
	cout << "================" << endl;
	cout << "   Welcome!!!   " << endl;
	cout << "  1. signup     " << endl;
	cout << "  2. login      " << endl;
	cout << "  3. record     " << endl;
	cout << "  4. help       " << endl;
	cout << "  5. exit       " << endl;
	cout << "================" << endl;
	cout << "your choice:";
	cin >> ch;
	return ch;
}
#endif

#pragma once
#ifndef SIGNUP_H
#define SIGNUP_H

#include "Common.h"


class player
{
private:
	string id;
	string pwd;
public:
	player() { id = ' '; pwd = ' '; }//constructor for signup
	loginfo input();//input user info(signup)
	void saveinput(bool c, loginfo l,const char* fi);//save input into file
	void confirm(const char* f);//check saved data
};
//input user info 
loginfo player::input()
{
	auto l = make_unique<loginfo>();//smart pointer
	string i,p,vp;
	int cnt = 0;
	fstream in;
	in.open(userDB, ios::in|ios::binary);

	cout << "====================" << endl;
	cout << "    signup          " << endl;
	cout << "    ID: ";
	cin >> i;
	//check id length(up to 8 characters.)
	if (i.length() > MAXLENGTH)
	{
		cout << "ID may have up to 8 characters !" << endl;
		i.clear();
		cout << "    ID: ";
		cin >> i;
	}
	//id duplication check
	while (in>>l->id>>l->pwd)
	{
		if (l->id == i)
		{
			cout << "duplicate id!" << endl;
			cout << "    ID: ";
			cin >> i;
		}
	}
	//check duplicate id
	l->id = i;
	p = setpass("   password:");//password masking
	if (p.length() > MAXLENGTH)//check password's length
	{
		cout << "Password may have up to 8 characters !" << endl;
		p.clear();
		p = setpass("   password:");
	}
	vp = setpass("   verify password: ");//password masking 
	while (p != vp)//when user-input is wrong
	{
		cout << "input error!" << endl;
		cnt++;
		if (cnt >= MAXNUM)//when user fail three times to verify password
		{
			cout << "failed to veify!" << endl;
			cout << "please start over!" << endl;
			exit(0);
		}
		vp = setpass("   verify password: ");	
	}
	l->pwd = p;
	return *(l);
}
//save input
void player::saveinput(bool c, loginfo l,const char* fi)
{
	fstream f;
	if (c == true)
	{
		f.open(fi, ios::out | ios::binary);
		if (!f)
		{
			cout << "failed to open!" << endl;
			exit(0);
		}
		else
		{
			cout << "saving..." << endl;
			f << l.id << " " << l.pwd << endl;
			cout << "registration complete." << endl;
			f.close();
		}
	}
	else
	{
		f.open(fi, ios::out | ios::app | ios::binary);
		if (!f)
		{
			cout << "failed to open!" << endl;
			exit(0);
		}
		else
		{
			cout << "appending..." << endl;
			f << l.id << " " << l.pwd << endl;
			cout << "successfully appended." << endl;
			f.close();
		}
	}	
}
//check whether signup succeed or not
void player::confirm(const char* f)
{
	loginfo l;
	fstream in;
	in.open(f, ios::in | ios::binary);

	if (!in)
	{
		cout << "failed to read!" << endl;
		exit(0);
	}
	while (in >> l.id >> l.pwd)
		   ;
	cout << "player info: " << endl;
	cout << "Id: " << l.id << "," << "Password:" << l.pwd << endl;
}

void showAll()
{
	auto l = make_unique<loginfo>();
	fstream in;
	in.open(userDB, ios::in);

	while (in>>l->id>>l->pwd)
	{
		cout << l->id << " " << l->pwd << endl;
	}
}
#endif

#include "signup.h"

int main(void)
{
	//initialization
	bool check = isExist(userDB);
	bool con = true;//signup continue?(default = true)
	string id, pwd;//for login
	int selection;//select menu

	selection = mainMenu();//call main menu

	switch (selection)
	{
	case 1:
		//signup
		while (con)
		{
			auto p = make_unique<player>();
			loginfo ll;

			ll = p->input();
			p->saveinput(check, ll, userDB);
			p->confirm(userDB);

			con = isContinue();
		}
		break;
	case 2:
		auto l = make_unique<loginfo>();//instantiate structure for user info
		fstream in;
		in.open(userDB, ios::in | ios::binary);//open the text file contains info

		cout << "id:";
		cin >> id;

		while (in >> l->id >> l->pwd)//read user info from text file
		{
			//to check id's correct or not
			if (l->id == id)//id match
			{
				pwd = setpass("password: ");//password masking
				if (l->pwd == pwd)//password match
				{
					cout << "user verified!" << endl;
					break;
				}
				else  //password mismatch
				{
					cout << "incorrect password." << endl;
					pwd = setpass("password:");//pwd reinput
				}
			}
			else
			{
				cout << "incorrect id" << endl;
			}
		}
		break;
	}
	system("pause");
	return 0;
}


Что я уже пробовал:

Я написал код для проверки целостности моего файла данных следующим образом;

автоматический L = make_unique&ЛТ;логинфо&ГТ;();
fstream in;
в.открыть(баз данных userdb, а iOS::в | ОС iOS::бинарные);

cout << " id:";
Cin> & gt; id;

а (в &ГТ;&ГТ; я-&ГТ;ИД &ГТ;&ГТ; я-&ГТ;инвалидов)
{
если (l- & gt;id = = id)
соиь << л-&ГТ;ИД &ЛТ;&ЛТ; "" &ЛТ;&ЛТ; л-&ГТ;дуо &ЛТ;< епси;
}

этот код прекрасно работал так, как я и предполагал. это меня очень смутило...

1 Ответов

Рейтинг:
2

KarstenK

Вы должны указать полный путь, иначе файл ДОЛЖЕН будьте в том же каталоге, что и ваш exe-файл. И: ваш процесс нуждается в правах на чтение или запись для этого файла.

Помните: пароли чрезвычайно чувствительны, поэтому они должны быть надежно зашифрованы. Хорошим подходом также является хранение только хэш-значения SHA-1.