#include <stdio.h>
#include <conio.h> // getch() 함수를 사용하기 위한 헤더 파일
#include <string.h> //문자열 비교함수인 "strcmp"를 사용하기 위해 string.h 라이브러리를 사용.
enum loginProgram {
userCreate = 1, // 회원가입
userLogin = 2, // 로그인
};
struct userInfo { // struct를 이용하여 로그인 정보 저장
char userId[100];
char userPassword[100];
char userCheckPassword[100];
};
struct userInfoCompare { // struct를 이용하여 로그인 시 아이디, 비밀번호 비교
char userId[100];
char userPassword[100];
};
void getPassword(char* password) { //비밀번호 비교를 위한 함수
char ch;
int i = 0; //사용자가 입력한 문자열 갯수
while (1) {
ch = _getch();
if (ch == 13) { // Enter 키를 누르면 종료
break;
}
else if (ch == 8) {
if (i > 0) {
printf("\b \b"); // 백스페이스 키 입력 시, 화면에서 지움
i--;
}
}
else {
password[i++] = ch; // 비밀번호 배열에 문자 추가
printf("*"); // 별표 출력
}
}
password[i] = '\0'; // 문자열 종료를 위한 널 문자 추가
printf("\n");
}
int main() {
enum loginProgram login_Type; // 사용자의 선택으로 로그인 프로그램 실행.
struct userInfo userCreateInfo;
struct userInfoCompare userLoginInfo;
do {
printf("로그인 프로그램\nBy.Nohsw");
printf("\n\n");
printf("[1. 회원가입]\n[2. 로그인]\n");
printf("입력: ");
scanf_s("%d", &login_Type); // 사용자의 선택 값으로 switch 실행.
printf("\n\n");
switch (login_Type) { //가독성 향상을 위해 enum 사용하였고, switch case를 작성.
case userCreate: //회원가입
printf("회원가입 화면입니다.\n");
printf("회원가입 할 ID를 입력해주세요.\n");
printf("입력: ");
scanf_s("%99s", userCreateInfo.userId, sizeof(userCreateInfo.userId));
//%99s를 사용한 이유: 버퍼 오버플로우를 방지하기 위해 입력받을 문자열의 크기를 명시를 해야한다.
// 버퍼 오버플로우: 버퍼 오버플로우는 배열의 크기를 초과하여 데이터를 저장하려고 할 때 발생하는 문제입니다.
// 이러한 문제를 방지하기 위해서는 배열의 크기를 확인하고, 데이터를 저장하기 전에 배열의 크기를 초과하지 않도록 조치해야 합니다.
//scanf_s 사용을 위해서는 크기 제한을 둔 %s를 사용하는게 좋다. (메모리 누수를 포함한 보안 문제를 방지하기 위함)
//위에 userId[100]으로 작성하였기에 null값인 \0을 제외한 %99s를 사용.
printf("비밀번호를 입력해주세요.\n");
printf("입력: ");
getPassword(userCreateInfo.userPassword);
printf("비밀번호를 한번 더 입력해주세요.\n");
printf("입력: ");
getPassword(userCreateInfo.userCheckPassword); //함수를 이용하여 1차와 2차 비밀번호 비교
//비밀번호 비교 후 맞으면 회원가입 성공, 틀리면 회원가입 실패 출력.
if (strcmp(userCreateInfo.userPassword, userCreateInfo.userCheckPassword) == 0) {
printf("회원가입 성공.\n");
printf("사용자의 아이디는 %s입니다.\n", userCreateInfo.userId);
}
else {
printf("회원가입 실패.\n");
printf("사유: 입력한 비밀번호가 다릅니다.\n");
}
printf("\n\n");
break;
case userLogin: //로그인
printf("아이디 입력: ");
scanf_s("%s", userLoginInfo.userId, sizeof(userLoginInfo.userId));
printf("비밀번호 입력: ");
getPassword(userLoginInfo.userPassword);
if (strcmp(userLoginInfo.userId, userCreateInfo.userId) == 0 && strcmp(userLoginInfo.userPassword, userCreateInfo.userPassword) == 0) {
printf("로그인 성공\n");
int i = 0;
int inputNum;
while (i < 1) {
printf("\n\n");
printf("%s님 어서오세요.\n", userLoginInfo.userId);
printf("종료하시려면 '-1'을 눌러주십시오.\n");
printf("입력: ");
scanf_s("%d", &inputNum);
switch (inputNum) {
case -1:
printf("\n\n");
printf("로그아웃을 진행합니다.\n");
i++;
printf("\n\n");
break;
default:
printf("\n\n");
printf("잘못된 값을 입력하였습니다. 로그아웃을 진행합니다.\n");
i++;
printf("\n\n");
break;
}
}
}
else {
printf("로그인 실패\n");
if (strcmp(userLoginInfo.userId, userCreateInfo.userId) == 1 && strcmp(userLoginInfo.userPassword, userCreateInfo.userPassword) == 1) {
printf("아이디와 비밀번호가 다릅니다. 다시 입력해주세요.\n");
}
else if (strcmp(userLoginInfo.userPassword, userCreateInfo.userPassword) == 1) {
printf("비밀번호가 다릅니다. 비밀번호를 다시 입력해주세요.\n");
}
else if (strcmp(userLoginInfo.userId, userCreateInfo.userId) == 1) {
printf("아이디가 다릅니다. 다시 입력해주세요.\n");
}
else {
printf("ERROR\n");
}
printf("\n\n");
}
break;
}
} while (1);
return 0;
}
어제의 코드를 살펴본 후 오늘은 로그인 코드를 입력해보았다.
로그인 구현 시 직접 코드를 만들어보았으며, 정상적으로 로그인이 되나 발견된 버그가 생겼다.
버그에 대해 수정 후 코드에 대해 익힌 후에 암호화를 배우는 것이 맞다고 판단하여 암호화는 마지막에 구현 할 예정이다.
지금까지 확인 된 버그 내용:
1. 회원가입 후 로그인 시 처음부터 아이디와 비밀번호가 모두 다르면 else문의 에러가 발생.
아이디나 비밀번호 중 하나만 맞으면 이후의 코드는 어떤 문제인지 정상 출력.
2. 로그인 이후 화면에서 defalut를 입력하였고, -1을 제외한 다른 키 입력 시 무한루프 발생.
임시로 default값에 i++ 를 입력하여 로그아웃이 진행되도록 조치.
'C 프로그래밍' 카테고리의 다른 글
C 프로그래밍 우분투 시작 (2) | 2023.12.03 |
---|---|
C언어 프로젝트 23.12.03 (4) | 2023.12.03 |
C언어 프로젝트 23.12.01 (1) (5) | 2023.12.01 |
C언어 프로젝트 23.12.01 (0) | 2023.12.01 |
C언어 프로젝트 23.11.30 (0) | 2023.11.30 |