Jump to content
figboy

Login em C

Recommended Posts

figboy

Boa noite a  todos. Tenho de fazer uma função para fazer login de um utilizador e tenho de usar ficheiros para guardar a informação dos utilizadores.

Sendo assim a minha ideia seria ter uma pasta em que cada ficheiro tem o como nome o próprio nome do utilizador e dentro desse ficheiro tinha a sua password.

A primeira coisa que estava a pensar fazer é abrir o diretório onde estão os ficheiros dos utilizadores e verificar se existe algum ficheiro com o nome de utilizador que foi introduzido ao fazer login.

O código que fiz foi este, mas está me a dar o erro "Falha de segmentação (imagem do núcleo gravada)" e não estou a conseguir perceber onde é o erro. Para além disso acho que não estou a conseguir fazer o que pretendo, mas não estou a ver como o fazer.

int login() 
{
	char user[20], pass[20];
	printf("utilizador:"); //nome de utilizador
	scanf("%s", &user);
	
	printf("Password:");
	scanf("%s", pass);  //password do utilizador
	
	DIR *acesso;
	struct dirent *d;
	acesso = opendir("Projeto/Login/Administradores");
	
	while ( (d =readdir(acesso)) != NULL){
		if ((d==user){
			printf("User encontrado");
		}
		else {
			printf("User não encontrado");
		}
		
				}
	 
}

 

Se alguém conseguir me dar umas luzes fico muito agradecido.

EDIT: Já percebi de onde vem o erro, é no caminho do opendir. Se eu puser o caminho completo já não dá erro(apesar de que continuo sem conseguir que a função faça o que preciso). Contudo eu não queria colocar o caminho completo, queria colocar o caminho apenas a partir de onde tenho o executável para conseguir que o programa funcione em qualquer pc, há maneira de fazer isto? Obrigado

Cumps 

Edited by figboy

Share this post


Link to post
Share on other sites
HappyHippyHippo

um caminho relativo é indicado com o .

o que deverias colocar seria : ./Projeto/Login/Administradores

o problema principal é que não validas o resultado da função opendir

além disso, não é assim que se compara strings ...


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
figboy

Obrigado já deu para resolver o erro, apesar de que tive de usar dois pontos em vez de um único ponto.

 

Agora não estou a conseguir fazer a comparação do nome dos ficheiros que estão no diretório com o nome que foi inserido pelo utilizador. O que tenho é isto.

int login() 
{
	char user[20], pass[20];
	printf("utilizador:"); //nome de utilizador
	scanf("%s", &user);
	
	printf("Password:");
	scanf("%s", pass);  //password do utilizador
	
	DIR *acesso;
	struct dirent *entry;
	acesso = opendir("../Projeto/Login/Administradores");
	
	if(!acesso){
		printf("Erro no opendir: %s\n", strerror(errno));
	}
	
	while ( (entry=readdir(acesso)) != NULL){
		if (strcmp(entry->d_name, user)==0){
			printf("User encontrado");
		}
		else {
			printf("User não encontrado");
		}
		
				}  
}

É na condição do while que estou a fazer mal ou tenho de  usar outros comandos?

Obrigado

Edited by figboy

Share this post


Link to post
Share on other sites
figboy

Muito obrigado pela tua ajuda. Consegui por essa parte a funcionar. 

Agora queria usar a manipulação de ficheiros para abrir o ficheiro desse utilizador e verificar se a palavra pass está errada mas tenho outra vez o erro de falha de segmentação mas pelo que vi não é no caminho do fopen e não estou a conseguir perceber de onde vem o erro. Já agora é possível usar uma variável num path? Por exemplo guardo o nome de usuário que é escrito na variável user e depois no path queria fazer isto : "./Projeto/Login/Adiministradores/user".

int login_pass(){
	char pass[20], pass1[20];
	
	printf("Password:");
	scanf("%s", &pass);
	
	FILE *password= fopen("../Projeto/Login/Administradores/figboy.txt", "r");
	
	if (!password){
		printf("Erro no fopen: %s", strerror(errno));
	}

		while((fscanf(password, "%s", pass1) !=EOF)) {
			if((strcmp(pass, pass1)==0)){
				printf("Login completo");
			}
			else{
				printf("Palavra pass errada");
			}
		}
	
}

Obrigado

Share this post


Link to post
Share on other sites
HappyHippyHippo

responde a esta simples questão : o que retorna a função fscanf ?


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
figboy

Já experimentei a por return 0 mas continuo com o mesmo erro.

int login_pass(){
	char pass[20], pass1[20];
	
	printf("Password:");
	scanf("%s", &pass);
	
	FILE *password= fopen("../Projeto/Login/Administradores/figboy.txt", "r");
	
	if (!password){
		printf("Erro no fopen: %s", strerror(errno));
	}

		while((fscanf(password, "%s", pass1) !=EOF)) {
			if((strcmp(pass, pass1)==0)){
				printf("Login completo");
				return 0;
				
			}
			else{
				printf("Palavra pass errada");
				return 0;
				
			}
		}
	
}

 

Share this post


Link to post
Share on other sites
figboy

Pelo que percebi o fscanf retorna a quantidade de correspondências realizadas ou o EOF quando chega ao fim do ficheiro ou quando encontra algum erro

Share this post


Link to post
Share on other sites
HappyHippyHippo

ok, agora que tens o valor no ficheiro na variável pass1, o que tens na variável pass ?

e se a função retorna um inteiro, que inteiro é esse ?


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
figboy

No  pass1 vou ter as strings que estiverem no ficheiro, neste caso será 123 porque é a única string que está no ficheiro. Na variável pass vou ter o que o usuário escreve, neste caso também 123. E acho que a função retorna 1 porque só encontra uma string

 

Share this post


Link to post
Share on other sites
HappyHippyHippo

indica em que parte do código indica que o valor retornado é 1


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
figboy

Eu diria que sim. Mas eu estou a aprender por isso é provável que esteja a pensar mal 

Share this post


Link to post
Share on other sites
HappyHippyHippo

antes de tudo, como nada nessa instrução indica retorno da função, logo nunca será resposta para a questão,

segundo, se é um segmentatin fault, deverias apresentar o código inteiro, porque pode muito bem ser noutro local


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
figboy

Aqui está o código completo

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>

 void login_user() 
{
	char user[20];
	printf("utilizador:"); //nome de utilizador
	scanf("%s", &user);
	
	
	DIR *acesso;
	struct dirent *entry;
	acesso = opendir("../Projeto/Login/Administradores");
	
	struct dirent {
    off_t    d_off;                 // offset para este dirent   
    char     d_name[];    // nome do arquivo 
};

acesso = opendir("../Projeto/Login/Administradores");

	if(!acesso){
		printf("Erro no opendir: %s\n", strerror(errno));
	}
	
while (acesso) {
    
    if ((entry = readdir(acesso)) != NULL) { //Verifica se existe o user
        if (strcmp(entry->d_name, user) == 0) {
            closedir(acesso);
            login_pass();
            
           		
        }
    }else {                                 
       if (errno == 0) {
         closedir(acesso);
           printf("user não encontrado\n");
           login_user();
       }
        closedir(acesso);
	}
}

}

int login_pass(){
	char pass[20], pass1[20];
	
	printf("Password:");
	scanf("%s", &pass);
	printf("Erro: %s",  strerror(errno));
	
	FILE *password= fopen("../Projeto/Login/Administradores/figboy.txt", "r");
	
	if (!password){
		printf("Erro no fopen: %s", strerror(errno));
	}

		while(fscanf(password,"%s\n", pass1) !=EOF  ){
		
			if((strcmp(pass, pass1)==0)){
				printf("Login completo");
				
				
			}
			else{
				printf("Palavra pass errada");
	
		}
	}
}
	

int main(void)
{
  printf("**Menu de Registo**\n");
  printf("1)Login/Autenticação\n");
  printf("2)Sair\n");
  int opcao;
  scanf("%d", &opcao);
  
  if (opcao==1){
	  login_user();
  }
  
  if (opcao==2){
	  exit(0);
  }
  
  if( opcao !=1 && opcao !=2){
	  printf("Escolha uma opção válida\n");
  }
  
 return 0; 
}

Então a verificação que estou a tentar fazer para a password está errada? Podes me dar umas luzes de como deveria fazer? É que não estou mesmo a ver como posso fazer.

Obrigado mais uma vez

Share this post


Link to post
Share on other sites
HappyHippyHippo

este é o output de compilação do teu código : 

src/main.c: In function 'login_user':
src/main.c:12:10: error: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[20]' [-Werror=format=]
  scanf("%s", &user);
         ~^   ~~~~~
src/main.c:12:10: error: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[20]' [-Werror=format=]
src/main.c:35:13: error: implicit declaration of function 'login_pass'; did you mean 'login_user'? [-Werror=implicit-function-declaration]
             login_pass();
             ^~~~~~~~~~
             login_user
src/main.c: In function 'login_pass':
src/main.c:55:10: error: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[20]' [-Werror=format=]
  scanf("%s", &pass);
         ~^   ~~~~~
src/main.c:55:10: error: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[20]' [-Werror=format=]
src/main.c:76:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^

tens de resolver isso primeiro ...

tem atenão ao argumento do teu scanf : pointeiro para o local onde irá guardar os dados

dica : pointeiro


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.