Code:
//PH's program: phprog.c
//Global variables are marked as v_*
//Local variables are marked as lv_*
//Axes variables are named as x and y
//Functions are marked as f_*
//Files are marked as file_*
//File locations are marked as c_*
//Structures are marked as s_*
#include<conio.h>
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#define v_length 17
void f_loginapproved(void); //Function prototypes.
void f_logout(void);
void f_read_pass(void);
void f_change_password(void);
void f_write_pass(char[v_length]);
void f_login_border(void);
void f_main_border(void);
void f_main_options(void);
void f_student_options(void);
char f_encrypt_password(char[v_length]);
void f_add_student(void);
void f_search_student(void);
void f_remove_student(void);
void f_dialog_border(void);
char f_clear_variable(char[]);
char v_uname[v_length]="Admin001"; //Default username and password global variables.
char v_passw[v_length]="password";
char c_filename[20]="login.dat"; //Password file for login.
char c_student_rec[20]="stud.dat";
char c_staff_rec[20]="staff.dat";
char v_garbage[20];
FILE *file_password;
FILE *file_student_rec;
FILE *file_staff_rec;
struct sgrades
{
int History;
int Geography;
int Math;
int English;
int Humanities;
int Science;
int Art;
int PE;
};
struct student_rec
{
int id;
char fname[15];
char lname[15];
char address[50];
int age;
char gender;
char phone[15];
struct sgrades s_grades; //88888888888
};
struct staff_rec
{
char fname[15];
char lname[15];
char address[50];
int age;
int id;
long int phone;
char gender;
double monthly_pay;
};
int main(void) //Main function used as login screen.
//Always int main(), with a return (0 is normal, by custom).
{
// clrscr();
//f_read_pass(); //Moves to function to update password variable.
//Can't call functions and make commands before you finish
//declaring your variables in Turbo C.
//Some later C standards will allow it.
char lv_name[v_length]=""; //Sets local input variables for login.
char lv_pass[v_length]="";
int lv_garbage; //8888888888
int lv_valid; //Sets variable to count attempts in loop.
int lv_attempt=0;
clrscr(); //8888888
f_read_pass(); //88888888888
do{
f_login_border(); //Draws login border.
gotoxy(32,25);
printf("Username:"); //Displays username and password labels.
gotoxy(32,27);
printf("Password:");
gotoxy(43,25);
gets(lv_name); //Gets input of username and password from user.
gotoxy(43,27);
gets(lv_pass);
f_encrypt_password(lv_pass);
if(strcmp(lv_name,v_uname)!=0 || strcmp(lv_pass,v_passw)!=0) //Compares inputted password and username with file-saved password and default username.
{
lv_attempt++;
lv_valid=0;
gotoxy(27,30);
printf("Incorrect username or password"); //Error message if wrong input.
getch();
clrscr();
}
else //If input is correct local variable valid is 1.
lv_valid=1;
}while(!lv_valid && lv_attempt<3); //Loops until more than 3 tries or valid is 1.
if(lv_attempt>2 && !lv_valid)
{
gotoxy(18,30);
printf("Sorry, maximum of three(3) attempts reached"); //Error message after 3 wrong tries.
getch();
}
else
{
f_loginapproved(); //Main menu function to display all options.
}
printf("\n\n\t\t\t press Enter when ready");
lv_garbage = getchar();
lv_garbage++;
return 0;
}
void f_loginapproved(void) //LoginApproved function to enter menu after login.
{
int lv_mainmenu=0; //Sets variable for user input.
int lv_choice=0;
int lv_counter=1;
int lv_garbage;
do{
clrscr();
gotoxy(37,14);
printf("Main Menu\n");
for(lv_counter=1;lv_counter<=5;lv_counter++)
{
printf("\n\n\t\t%i.",lv_counter);
}
gotoxy(19,17);
printf("Main Options"); //1.
gotoxy(19,19);
printf("Student Options"); //2.
gotoxy(19,21);
printf("Staff Options"); //3.
gotoxy(19,23);
printf(""); //4.
gotoxy(19,25);
printf("Exit"); //5.
gotoxy(17,29);
printf("Input:");
f_main_border(); //Draws main border around main menu.
gotoxy(23,29);
scanf("%i",&lv_mainmenu);
lv_garbage=getchar(); //888888888 not v_garbage
switch(lv_mainmenu) //Checks user input with possible answers.
{
case 1: //Main Options.
{
f_main_options();
break;
}
case 2: //Student Options.
{
f_student_options();
break;
}
case 3: //Not specified.
{
printf("Sorry, this option is currently unavailable");
getch();
lv_choice=0;
break;
}
case 4: //Not specified.
{
printf("Sorry, this option is currently unavailable");
getch();
lv_choice=0;
break;
}
case 5: //Logout.
{
f_logout();
lv_choice=1;
break;
}
default: //If any other character is inputted.
{
f_dialog_border();
gotoxy(19,25);
printf("Invalid entry. Please use numeric values only.");
getch();
lv_choice=0;
break;
}
}
}while(lv_choice==0); //End of while loop.
lv_garbage++;
}
void f_read_pass(void) //Read password function to read saved password file.
{
if((file_password=fopen(c_filename,"rb+"))==NULL) //Opens password file and checks if empty.
{
printf("No password, default=password");
getch();
f_encrypt_password(v_passw); //Encrypts default password.
clrscr();
}
else
fscanf(file_password,"%s",v_passw); //Reads password and updates variable.
fclose(file_password);
}
void f_change_password(void) //Password function to edit password variables.
{
char lv_pass[v_length]="";
char lv_garbage;
clrscr();
f_main_border();
gotoxy(34,14);
printf("Change Password");
gotoxy(15,16);
printf("Use this option to change your login password. Make sure");
gotoxy(17,17);
printf("it is a password that you remember. Your password is");
gotoxy(19,18);
printf("encrypted and safely stored until next login.");
gotoxy(15,23);
printf("Enter current password: "); //Current password test before edit.
gets(lv_pass);
f_encrypt_password(lv_pass);
if(strcmp(lv_pass,v_passw)!=0) //Asks for current password before prompting for new password.
{
f_dialog_border();
printf("Wrong current password entered. The password has not been");
gotoxy(14,26);
printf("changed. Press any key to return to Main Options menu..."); //Error message, does not change password and returns to main menu.
getch();
}
else
{
gotoxy(15,28);
printf("Enter new password [17 characters max]: "); //Request new password.
f_clear_variable(lv_pass); //Empties lv_pass array to be used.
gets(lv_pass);
lv_garbage=getchar(); //8888888
f_write_pass(lv_pass); //Sends lv_pass array to function as argument.
f_dialog_border();
gotoxy(29,25);
printf("Password has been changed.");
getch();
}
lv_garbage++;
}
void f_write_pass(char lv_npass[]) //Password writing function to edit password.
{
f_encrypt_password(lv_npass); //Sends lv_pass to be encrypted before continue.
strncpy(v_passw,lv_npass,v_length); //Updates global variable with new password.
file_password=fopen(c_filename,"wb+"); //Erases old password file with blank.
fprintf(file_password,"%s",v_passw); //Saves new password in blank file.
fclose(file_password);
}
void f_logout(void) //Logout function to exit program at main menu.
{
char lv_cancel;
f_dialog_border();
gotoxy(22,25);
printf("Logging out. Press any key to exit program..."); //Displays logout message.
getch();
}
void f_main_options(void) //Main options funtion to personalise menu.
{
int lv_options=0;
int lv_choice=0;
int lv_counter=1;
int lv_garbage;
do{
clrscr();
gotoxy(35,14);
printf("Main Options\n"); //Title of menu.
for(lv_counter=1;lv_counter<=5;lv_counter++) //Loop lays out numbers for menu.
{
printf("\n\n\t\t%i.",lv_counter);
}
gotoxy(19,17);
printf("Change Password"); //1.
gotoxy(19,25);
printf("Return to Main Menu"); //5.
gotoxy(17,29);
printf("Input:");
f_main_border(); //Draws main border around labels.
gotoxy(23,29);
scanf("%i",&lv_options); //Gets user input.
lv_garbage=getchar(); //888888888
switch(lv_options)
{
case 1: //Change Password.
{
f_change_password();
lv_choice=0;
break;
}
case 2: //Not Specified.
{
f_dialog_border();
printf("Sorry, this option is currently unavailable");
getch();
lv_choice=0;
break;
}
case 3: //Not Specified.
{
f_dialog_border();
printf("Sorry, this option is currently unavailable");
getch();
lv_choice=0;
break;
}
case 4: //Not Specified.
{
f_dialog_border();
printf("Sorry, this option is currently unavailable");
getch();
lv_choice=0;
break;
}
case 5: //Return to Main Menu.
{
lv_choice=1;
break;
}
default: //If any other characters are inputted.
{
f_dialog_border();
gotoxy(19,25);
printf("Invalid entry. Please use numeric values only.");
getch();
lv_choice=0;
break;
}
}
}while(!lv_choice); //End of while loop.
lv_garbage++;
}
void f_login_border(void) //Login border function to draw border on login.
{
int x=23; //Sets variables X,Y as horizontal and vertical lines.
int y=24;
gotoxy(x,x); //This is the top left corner.
cprintf("%c",201);
gotoxy(60,x); //This is the top right corner.
cprintf("%c",187);
gotoxy(x,31); //This is the bottom left corner.
cprintf("%c",200);
gotoxy(60,31); //This is the bottom right corner.
cprintf("%c",188);
for(y=24;y<=30;y++) //This is the loop that makes the vertical lines.
{
gotoxy(23,y);
cprintf("%c",186);
gotoxy(60,y);
cprintf("%c",186);
}
y=23; //Resetting variable values for use in next loop.
x=24;
for(x=24;x<60;x++) //This is the loop that makes the horizontal lines.
{
gotoxy(x,y);
cprintf("%c",205);
gotoxy(x,31);
cprintf("%c",205);
gotoxy(x,29);
cprintf("%c",196);
}
gotoxy(23,29); //This is the 'T' for the left vertical line.
cprintf("%c",199);
gotoxy(60,29); //This is the 'T' for the right vertical line.
cprintf("%c",182);
}
void f_main_border(void) //Main border function to draw borders on menus.
{
int x=10; //Sets variables X,Y for horizontal and vertical lines.
int y=14;
gotoxy(10,13); //This is the top left corner.
cprintf("%c",201);
gotoxy(74,13); //This is the top right corner.
cprintf("%c",187);
gotoxy(10,34); //This is the bottom left corner.
cprintf("%c",200);
gotoxy(74,34); //This is the bottom right corner.
cprintf("%c",188);
for(y=14;y<=33;y++) //This loop makes the vertical lines on both sides.
{
gotoxy(x,y);
cprintf("%c",186);
gotoxy(x+64,y);
cprintf("%c",186);
}
y=13; //Resetting variable values for use in next loop.
x=11;
for(x=11;x<74;x++) //This loop makes the horizontal lines above and below.
{
gotoxy(x,y);
cprintf("%c",205);
gotoxy(x,y+2);
cprintf("%c",196);
gotoxy(x,y+21);
cprintf("%c",205);
}
gotoxy(10,y+2); //This is the 'T' for the left vertical line.
cprintf("%c",199);
gotoxy(74,y+2); //This is the 'T' for the right vertical line.
cprintf("%c",182);
}
void f_dialog_border()
{
int x=8;
int y=20;
gotoxy(7,20); //This is the top left corner.
cprintf("%c",201);
gotoxy(77,20); //This is the top right corner.
cprintf("%c",187);
gotoxy(7,31); //This is the bottom left corner.
cprintf("%c",200);
gotoxy(77,31); //This is the bottom right corner.
cprintf("%c",188);
for(x=8;x<=76;x++) //This loop creates the horizontal lines.
{
gotoxy(x,y);
cprintf("%c",205);
gotoxy(x,y+11);
cprintf("%c",205);
}
y=21;
for(y=21;y<31;y++) //This loop creates the vertical lines.
{
gotoxy(7,y);
cprintf("%c",186);
printf("\t\t\t\t\t\t\t\t\t");
gotoxy(77,y);
cprintf("%c",186);
}
gotoxy(13,23);
}
char f_encrypt_password(char lv_pass[]) //Encrypts password for security.
{
int lv_counter=0;
int lv_length=strlen(lv_pass);
for(lv_counter=0;lv_counter<=lv_length;lv_counter++) //Changes every character in password string.
{
lv_pass[lv_counter]=2*lv_pass[lv_counter]+15;
}
return lv_pass[v_length]; //Returns encrypted password to last function.
}
void f_student_options(void) //Student Options Menu function.
{
int lv_counter=1;
int lv_choice=0;
int lv_s_options=0;
int lv_garbage;
do{
clrscr();
gotoxy(34,14);
printf("Student Options\n"); //Menu title.
for(lv_counter=1;lv_counter<=4;lv_counter++) //Loop lays out numbers in menu.
{
printf("\n\n\t\t%i.",lv_counter);
}
gotoxy(19,17);
printf("Add Student"); //1.
gotoxy(19,19);
printf("Search for Student"); //2.
gotoxy(19,21);
printf("Remove Student"); //3.
gotoxy(19,23);
printf("Return to Main Menu"); //4.
gotoxy(17,29);
printf("Input:");
f_main_border();
gotoxy(23,29);
scanf("%i",&lv_s_options);
lv_garbage=getchar();
//888888888 ?? ===> lv_s_options;
switch(lv_s_options)
{
case 1: //Add Student.
f_add_student();
lv_choice=0;
return;
case 2: //Search for Student.
f_search_student();
lv_choice=0;
return;
case 3: //Remove Student.
f_remove_student();
lv_choice=0;
return;
case 4: //Return to Main Menu.
lv_choice=1;
break;
default:
f_dialog_border();
gotoxy(19,25);
printf("Invalid entry. Please use numeric values only.");
lv_choice=0;
getch();
return;
}
}while(!lv_choice);
lv_garbage++;
}
void f_add_student(void)
{
int lv_id;
int lv_garbage;
struct student_rec s_students; //888888888888 add "struct"
char lv_continue;
int lv_cancel;
clrscr();
if((file_student_rec=fopen(c_student_rec,"rb+"))==NULL)
{
f_dialog_border();
gotoxy(13,24);
printf("First student addition, a file will be created to store your");
gotoxy(37,27);
printf("information.");
getch();
s_students.id=1;
clrscr();
file_student_rec=fopen(c_student_rec,"a+");
}
else
{
do{
// lv_id=s_students.id;
}while(fread(&s_students,sizeof(s_students),1,file_student_rec));
// }while(!feof(file_student_rec));
s_students.id=lv_id+1;
}
f_clear_variable(s_students.fname);
f_clear_variable(s_students.lname);
f_clear_variable(s_students.address);
f_clear_variable(s_students.phone);
s_students.age=0;
s_students.gender=0x00;
do{
clrscr();
gotoxy(36,14);
printf("Add Student");
gotoxy(15,17);
printf("ID: %05i",s_students.id);
gotoxy(15,19);
printf("First Name:");
gotoxy(15,21);
printf("Last Name:");
gotoxy(15,23);
printf("Address:");
gotoxy(15,25);
printf("Age:");
gotoxy(15,27);
printf("Gender:");
gotoxy(15,29);
printf("Phone Number:");
f_main_border();
gotoxy(28,19);
gets(s_students.fname);
gotoxy(27,21);
gets(s_students.lname);
gotoxy(24,23);
gets(s_students.address);
gotoxy(20,25);
scanf("%i",&s_students.age);
lv_garbage=getchar();
gotoxy(23,27);
scanf("%c",&s_students.gender);
lv_garbage=getchar();
gotoxy(30,29);
gets(s_students.phone);
f_dialog_border();
printf("Are you sure you want to add this student to student records[y/n]?");
scanf("%c",&lv_continue);
lv_garbage=getchar();
if(lv_continue=='n' || lv_continue=='N')
lv_cancel=1;
else
lv_cancel=0;
}while(lv_cancel==1);
s_students.s_grades.History=0;
s_students.s_grades.Geography=0;
s_students.s_grades.Math=0;
s_students.s_grades.English=0;
s_students.s_grades.Humanities=0;
s_students.s_grades.Science=0;
s_students.s_grades.Art=0;
s_students.s_grades.PE=0;
fwrite(&s_students,sizeof(s_students),1,file_student_rec); //888888
fclose(file_student_rec);
lv_garbage++;
}
void f_search_student(void)
{
clrscr();
getch();
}
void f_remove_student(void)
{
clrscr();
getch();
}
char f_clear_variable(char lv_dirty[]) //Cleans out array for re-use.
{
int lv_counter=0;
for(lv_counter=0;lv_counter<50;lv_counter++)
{
lv_dirty[lv_counter]=0x00;
}
return lv_dirty[strlen(lv_dirty)];
}
Edit: I wanted to strongly second MK's suggestion with emphasis on checking *every* function, and every block of code, for proper function and accuracy before you go on to the next one. Even if you need to use stubs for functions initially, that's fine.