I am trying to read a .txt file using C++, in which the user enters (in this case a "user" and a "pass") two pieces of information, and when they are compared, if both are present, a type " Correct login". The code is the following:
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main(){
ifstream archivo("user.txt");
//Obtencion de datos
cout << "Usuario: ";
char user[25];
cin.getline(user,25,'\n');
cout << "Pass: ";
char pass[25];
cin.getline(pass,25,'\n');
//Creacion de la linea a buscar
char busqueda[100];
strcpy(busqueda, user);
strcat(busqueda, " ");
strcat(busqueda, pass);
char linea[100];
while(!archivo.eof() || busqueda != linea){
for(int i = 0; i!=archivo.eof(); i++){
archivo.getline(linea, 100);
}
}
cout << endl << endl << "LOGIN CORRECTO." << endl << linea;
return 0;
}
The problem is that once you enter the two data, you get stuck in an infinite loop where you do nothing. You can be giving it an intro all the time it doesn't come out of there...
Doing more tests, I have arrived at the following code. The only thing is that it only compares with the first line of the file.
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
struct registro{
string name;
string second;
string street;
string user;
string pass;
} usuario;
void registroUsuario(){
ofstream archivo("registro.txt");
archivo << "----------------------" << endl;
archivo << "Nombre: " << usuario.name << endl;
archivo << "Apellido: " << usuario.second << endl;
archivo << "Direccion: " << usuario.street << endl;
archivo << "Usuario: " << usuario.user << endl;
archivo << "Password: " << usuario.pass << endl;
archivo.close();
}
void registroLogin(){
ofstream archivo("usuarios.txt");
archivo << usuario.user;
archivo << " ";
archivo << usuario.pass;
archivo << "\n";
archivo.close();
}
bool login(string usuario, string password){
ifstream archivo("usuarios.txt");
string busqueda = usuario + " " + password;
string linea;
while(!archivo.eof()){
getline(archivo, linea);
if(linea == busqueda){
return true;
}
else{
return false;
}
}
}
int main(){
menu:
cout << "\t\t\t *** Base de datos ***" << endl << endl;
cout << "1. Registro de usuario" << endl;
cout << "2. Login" << endl;
cout << "0. Salir" << endl << endl;
cout << "Escoge una opcion: ";
int option;
cin >> option;
cin.ignore();
cout << endl << endl;
system("pause");
switch(option){
case 1:{
system("cls");
cout << "Nombre: ";
getline(cin, usuario.name);
cout << endl << "Apellido: ";
getline(cin, usuario.second);
cout << endl << "Direccion: ";
getline(cin, usuario.street);
cout << endl << endl << "Nombre de usuario: ";
getline(cin, usuario.user);
cout << endl << "Password: ";
getline(cin, usuario.pass);
registroUsuario();
registroLogin();
cout << endl << endl;
system("pause");
goto menu;
break;
}
case 2:{
system("cls");
cout << "Usuario: ";
getline(cin, usuario.user);
cout << endl << "Password: ";
getline(cin, usuario.pass);
if(login(usuario.user, usuario.pass) == true){
goto login;
}
else{
cout << endl << endl << "Login incorrecto.";
goto menu;
}
break;
}
}
login:
cout << endl << endl << endl << "LOGIN CORRECTO";
return 0;
}
No need to reinvent the wheel for this, you can store your type objects
registro
in anstd::map
indexed by name:I advise you to create a function that saves records to file:
And another one that reads the file and fills in the map
registros
:This way, it's easy to check if a user exists and its password matches, by delegating to the
std::map::find
functionmap
:The function
std::getline
reads complete lines and returns the stream (" stream ") that performed the reading, this stream has a conversion operator to boolean that, if the stream is in the correct state, will return true (more details here ).