DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C (http://www.daniweb.com/forums/forum118.html)
-   -   Can Someone please check my project & comment/tips (http://www.daniweb.com/forums/thread21750.html)

byte_me Apr 11th, 2005 4:50 am
Can Someone please check my project & comment/tips
 
/* v_regdb.c ****************************************************************/
/*                                                                          */
/*                                                                          */
/*                                                                          */
/*        This is a maintenance program for an existing Vehicle Database.          */
/* The program is an interactive menu system, which allows the user to      */
/*        edit, delete and insert records into an existing database.              */
/*        All input is validated with any relevent error messages, should an      */
/*        error occur. In the event of an error the input is not written to file  */
/*        and the user is returned to the Main Menu screen.                        */
/*                                                                          */
/*                                                                          */
/*                                                                          */
/****************************************************************************/

/* Header files *************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <time.h>

#define  FILENAME "VREGDB.DAT"/* This is the actual file used -            */
                                                                                /* initialized & working (26000 records)    */
                                                                                /* record no. 000 - 25999.                  */
/*Structure Declarations ****************************************************/
                                                  /********************************************************/
struct t_date{      /*  tag ~ t_date stores the  tempory date & checks if a */
                                                  /* specific file has existing data or not .            */
        int  temp_day;  /* format DD.                                          */
        int  temp_month; /* format MM.                                          */
}temp_date;        /* var temp_date is declared as an instace of struct    */
                                                  /* t_date.                                              */
                                                  /********************************************************/
                                                                                /*********************************************/
struct date{                  /* tag ~ date stores the actual date.        */
        int  day;                  /* format DD.                                */
        int  month;                /* format MM.                                */
};                            /*********************************************/
                              /*********************************************/ 
struct pnc{                    /*tag ~ pnc stores the main data input.      */
        int  RecNo;                /* Record Number.                            */
        char V_RegNo  [8];        /* Vehicle Registration Number.              */
        struct date V_Regdate;      /* struct of type date.                      */
        char V_Maker  [11];        /* Vehicle Manufacturer.                    */
        char V_Model  [11];        /* Vheicle Model.                            */
        char V_Colour  [9];        /* Vehicle Colour.                          */
        char V_Owner  [26];        /* Vehicle Owners Name.                      */
        char V_Address[31];        /* Vehicle Owners Address.                  */
        struct date V_Expiry;      /* struct of type date.                      */
}vehicle;                      /* var vehicle is declared as an instance    */
                                                                                /* of struct pnc.                            */
                                                                                /*********************************************/
/*Function Declarations *****************************************************/
                                                                                /*********************************************/
int  validate_VReg(char *reg); /* Validates The Vehicle Reg Format & returns*/
                                                                                /* an error message or a valid Record Number */

void error_scr(char *reason, int delay);/* Dislays any errors on the screen */

void gotoxy(int col, int row); /* Mainly used for screen positioning        */

void clrscr(void);            /* Used to clear screen between displays    */

void pause_msg(int ln_x, int ln_y,char *msg, int delay);/*Displays a message*/
                                                                                /* on the screen for a given length of time. */
void input_details(void);      /*Inputs data from the user.                */

                                                                                /*********************************************/
/*Globle Variables **********************************************************/
                                                                                /*********************************************/
int  ch,flag,recno;
char temp_regno[8],choice, Str;
int  ESC = 27;                /* Esc Used to escape or end program          */

FILE *fp;                    /* Pointer to FILE                            */
                                                                                /**********************************************/
/*Star of Main **************************************************************/
void main()
{
/* Test to see if the file exists and it can be opened in read mode.
  If an error is detected print a message & terminate the program. */
        if((fp=fopen(FILENAME,"rb"))==NULL)
        {
                error_scr("ERROR ! READING FILE!", 3);
                exit(1);
        }

        while(1)          /* Start of infinate loop */
        {
               
/* Start of main menu with a list of choises*/
                printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
                printf("\n%13s||%20sMAIN MENU%21s||","","","");
                printf("\n%14s\\\\________________________________________________//","");
                printf("\n\n\n%30s1 : Add New Vehicle"
                                        "\n\n%30s2 : Edit Details"
                                        "\n\n%30s3 : Delete Entry"
                                "\n\n%28sESC : Exit          [ ] ","","","","");
                gotoxy(51,13);
                choice = getch();
                switch(choice)
                {
                        case '1' :/*If 1 is chosen then Add Vehicle Details page is displayed*/
                        {
                                clrscr();
                                if((fp=fopen(FILENAME,"wb"))==NULL)
                                {
                                        error_scr("ERROR ! READING FILE!", 3);
                                        exit(1);
                                }
                                printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
                                printf("\n%13s||%15sADD VEHICLE DETAILS%16s||","","","");
                                printf("\n%14s\\\\________________________________________________//","");
                                gotoxy(18,7);printf("Enter Vehicle Reg No. : ");
                                gets(vehicle.V_RegNo);

/* Flags are use mostley in validate_VReg() Function to determin wheather a
        specific event has taken place. If so they are set again within Validate_VReg()
        in order to inform the program how to execute the rest of the statements in
        case '1':  i.e. If an error is detcted while in the validation process an
        error message is displayed control is returned to main(); */

                                flag=0;
                                validate_VReg(vehicle.V_RegNo);
                                if(flag==1)
                                        break;      /*Return to main menu */
                                input_details();

/* The user is asked if they wish to add the new record. If they dont choose
        the letter y A message is displayed and the user is returned to the main menu.
        If y is chosen the record is added. */
                                gotoxy(18,16);        printf("Are you sure you want to INSERT this record  [ ]");
                                gotoxy(65,16);
                                ch=toupper(getch());
                                if(ch != 'Y')
                                {
                                                pause_msg(32,17,"RECORD NOT INSERTED!",3);
                                                break;    /*Return to main menu */
                                }
                                fread(&vehicle,sizeof(vehicle),1,fp);  /* Read the file */

/* Check if the record exists. Write it to file if it dosent exist else display
        a message. */
                        if(vehicle.V_Regdate.day == 99 || vehicle.V_Regdate.month == 99)
                                {
                                        vehicle.V_Regdate.day=temp_date.temp_day ;
                                        vehicle.V_Regdate.month=temp_date.temp_month;
                               
                                        fwrite(&vehicle,sizeof(vehicle),1,fp);
                                        pause_msg(32,17,"RECORD ADDED!",3);
                                        break;      /*Return to main menu */
                                }
                                else
                                {
                                        error_scr("A RECORD ALLREADY EXISTS!",3);
                                                break;  /*Return to main menu */
                                }
                        }
                        case '2' :/*If 2 is chosen then ammend Vehicle Details page is displayed*/
                        {
                                clrscr();
                                printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
                                printf("\n%13s||%14sAMMEND VEHICLE DETAILS%14s||","","","");
                                printf("\n%14s\\\\________________________________________________//","");
                                gotoxy(18,7);printf("Enter Vehicle Reg No. : ");
                                gets(vehicle.V_RegNo);
                                flag=1;
                                validate_VReg(vehicle.V_RegNo);  /*Validate the registration number*/
                                if(flag==1)                  /*flag is set to 1 if an error occured*/
                                        break;                    /*Return to main menu */

/*Test to see if the record exists, if not display a message*/
                                if((vehicle.V_Regdate.day == 99) && (vehicle.V_Regdate.month== 99))
                                {
                                        pause_msg(32,17,"RECORD DOSE NOT EXIST!",3);
                                                break;    /*Return to main menu */
                                }
                                flag=0;
/*If the record exists input all the details*/
                                input_details();

/*Get confirmation before ammending the record*/
                                gotoxy(18,16);printf("Are you sure you want to AMMEND this record  [ ]");
                                gotoxy(65,16);ch=toupper(getch());
                                if(ch != 'Y')
                                {
                                        pause_msg(32,17,"RECORD NOT AMMENDED!",3);
                                                break;    /*Return to main menu */
                                }
/* The record is then written, and confirmation
        is displayed*/
                                fwrite(&vehicle,sizeof(vehicle),1,fp);
                                pause_msg(32,17,"RECORD AMMENDED!",3);
                                        break;      /*Return to main menu */
                        }

                        case '3' :/*If 3 is chosen then delete Vehicle Details page is displayed*/
                        {
                                clrscr();
                                printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
                                printf("\n%13s||%14sDELETE VEHICLE DETAILS%14s||","","","");
                                printf("\n%14s\\\\________________________________________________//","");
                                gotoxy(18,7);printf("Enter Vehicle Reg No. : ");
                                gets(temp_regno);
                                flag=0;
                                validate_VReg(temp_regno);
                                if(flag==1)
                                        break;      /*Return to main menu */
/*A warning message is displayed on the screen and the user is prompted for
  confirmation to delete the record*/
                                gotoxy(35,9);printf("WARNING!!");
                                gotoxy(18,10);printf("Are you sure you want to DELETE this record  [ ]");
                                gotoxy(65,10);        ch=toupper(getch());
                                if(ch != 'Y')
                                {
                                        pause_msg(32,17,"RECORD NOT DELETED!",3);
                                                break;    /*Return to main menu */
                                }
                                fread(&vehicle,sizeof(vehicle),1,fp);
                                if(vehicle.V_Regdate.day==99 && vehicle.V_Regdate.month==99)
                                {
                                        error_scr("REG NO.DOESN'T EXIST",3);
                                                break;    /*Return to main menu */
                                }
/*If the record exists change the dates to 99 & write it to disc*/
                                vehicle.V_Regdate.day=99 ;
                                vehicle.V_Regdate.month=99;
                               
                                fwrite(&vehicle,sizeof(vehicle),1,fp);
                                pause_msg(32,17,"RECORD DELETED!",3);
                                        break;          /*Return to main menu */
                        }
/* If the Esc button is pressed the program terminates normally after displaying
        the exit screen*/
                        case 27 :
                        {
                                fclose(fp);        /*Close the opened file*/
                                clrscr();
                                printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
                                printf("\n%13s||%15sPROGRAM TERMINATED%17s||","","","");
                                printf("\n%14s\\\\________________________________________________//","");
                                printf("\n\n\n%20sThank You for using this Vehicle Database!"
                                                "\n\n\n\n%31sProgrammer : K.Angel"
                                                "\n\n\n%38s2005.","","","","","","","");
                                                exit(0);    /* Normal termination  of the program */
                                                break;      /*This break is never reached */
                        }
                        default : /* If an invalid choise was made a message is displayed*/
                        error_scr("INVALID CHOICE!",2);  /*Return to main menu after running
                                                                                                                /*error message */
                }
        }
}
/************************************************************** End of Main */

/* Functions ****************************************************************/
/****************************************************************************/
/* Func ~                                                                  */
/*          int validate_vReg( char *reg);                                  */
/*          ==============================                                  */
/*          This function is used to validate the format of the vehicle    */
/*          registration input by the user.                                */
/*          It also creates a unique record number which is used to        */
/*          calculate the offset for the file pointer positioning.          */
/*          The record size (sizeof(vehicle)) is multiplied by the record  */
/*          number to give the offset from the begining of the file        */
/*          (SEEK_SET).                                                    */
/*          The file pointer is tested to see if it is starting off at      */
/*          position 0. The program will terminate with an error message    */
/*          if the statement is not true.                                  */
/*Arguments~                                                                */
/*          A string (vehicle regitration number) input by the user is      */
/*          passed to the function.                                        */
/*Returns ~                                                                */
/*        nill                                                            */
/****************************************************************************/
int validate_VReg(char *reg)
{
        /*Local variable ~ only visable within Func validate_VReg();*/
        char *str, *str_ptr=vehicle.V_RegNo;
        int  j=0, x=0, i=0;

        while(i<7)
        {
/*Test Format of the Registration number*/
                if((!isalpha(reg[0]))||(!isdigit(reg[1]))||
                        (!isdigit(reg[2]))||(!isdigit(reg[3]))||
                        (!isalpha(reg[4]))||(!isalpha(reg[5]))||
                        (!isalpha(reg[6])))
                {
/*If an error is detected print an error message and set the flag to 1 to
  inform the next program executable statement that an error has occured*/
                        error_scr("ERROR - Invalid Reg Format", 2);
                        flag = 1;
                        return (0);
                }
/*If no error in the file format. Convert the first Charater to uppercase*/
                if(i==0)
                {
                        ch = toascii(reg[0]);
                        ch=toupper(ch);
                        str_ptr++;
                }
/*Covert the character into its integer value*/
                if(i==1)
                {  str = str_ptr;
                        j= atoi(str);
                }
                i++;
        }
/*Formula to create th record number*/
        x = ch - 65;
        recno = (x * 1000) + j;
/*Move the fp to the correct possition & test it if an error is detected display
  an error message and terminate the program*/
        if(fseek(fp,(recno * sizeof(vehicle)),SEEK_SET)!=0)
        {
                error_scr("FILE READ ERROR! EXITING PROGRAM",4);
                exit(1);
        }

/*The flag is set to 0 in Add case 1 so at this point the program will continue
 to execute passed this flag test. In case 2 the flag is set to 1 so at this
 flag test the program returns to main(). The flag is reset to 0 to indecate
 no errors occured*/
        if(flag == 1)
        {
                flag=0;
                return(0);
        }
        /*Display the vehicle record number only in case 1 as case 2 never
          reaches here*/
        gotoxy(18,5);printf("VEHICLE RECORD NUMBER : %d", recno);
        vehicle.RecNo = recno;

        return(0);
}
/********************************************** End of Func validate_VReg() */

/****************************************************************************/
/* Func ~                                                                  */
/*          void error_scr(char *msg, int delay);                          */
/*          =====================================                          */
/*          This function displays a message under the title ERROR for a    */
/*          short period of time. The message is displayed through a        */
/*          seperate function call.                                        */
/*Arguments~                                                                */
/*          There are two arguments passed to this function.                */
/*          First is a string which is used to dislay the appopriate        */
/*          message on the screen.                                          */
/*          The second argument is used to store a number wich determins    */
/*          the length of time to display the message.                      */
/*Returns ~                                                                */
/*        void.                                                            */
/****************************************************************************/
void error_scr(char *msg, int delay)
{
        clrscr();
        printf("\n%14s//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\\\\","");
        printf("\n%13s||%21sERROR!%23s||","","","");
        printf("\n%14s\\\\________________________________________________//","");
        pause_msg(30,9,msg,delay); /*Display a message*/
}
/************************************************** End of Func error_scr() */

/****************************************************************************/
/* Func ~                                                                  */
/*          void pause_msg(int ln_x, int ln_y,char *msg, int delay);        */
/*          ========================================================        */
/*          This function displays a message on the screen for a given      */
/*          amount of time.                                                */
/*          It uses the standard C function time() & is measured in seconds.*/
/*Arguments~                                                                */
/*          There are four arguments passed to this function.              */
/*          1. int ln_x & int ln_y position the message on screen.          */
/*          3. char *msg the actual message.                                */
/*          4. int delay the length of time to display the message.        */
/*Returns~                                                                  */
/*        void.                                                            */
/****************************************************************************/
void pause_msg(int ln_x, int ln_y,char *msg, int delay)
{
        time_t start;
        time_t current;
        time(&start);
        gotoxy(ln_x,ln_y);printf(msg);fflush(stdin);
        do
        {
                time(&current);
        }
        while(difftime(current,start) < delay);
                clrscr();
}
/**************************************************** End of Func pause_msg */

/****************************************************************************/
/* Func ~                                                                  */
/*          void input_details(void);                                      */
/*          =========================                                      */
/*          This function allows the user to input data to store.          */
/*          It's a simple function that cuts down on repetative coding      */
/*Arguments~                                                                */
/*          void                                                            */
/*Returns ~                                                                */
/*          void                                                            */
/****************************************************************************/
void input_details(void)
{
        gotoxy(24,8); printf("Reg Date  DD/MM : ");
        scanf("%d%[ -/.,\n]%d",&temp_date.temp_day,&Str, &temp_date.temp_month);
        fflush(stdin);
        gotoxy(24,9);        printf("Vehicle Make    : ");
        gets(vehicle.V_Maker);
        gotoxy(24,10);        printf("Model          : ");
        gets(vehicle.V_Model);
        gotoxy(24,11);        printf("Colour          : ");
        gets(vehicle.V_Colour);
        gotoxy(24,12);        printf("Owners Name    : ");
        gets(vehicle.V_Owner);
        gotoxy(24,13);        printf("Address        : ");
        gets(vehicle.V_Address);
        gotoxy(22,14);        printf("Expiry Date DD/MM : ");
        scanf("%2d%[ -/.,\n]%2d",&vehicle.V_Expiry.day,&Str,&vehicle.V_Expiry.month);
  fflush(stdin);
}
/********************************************** End of Func input_details() */

/********************************************************* End of Functions */
Please don't post any length of code without using code tags. -Narue
:?:

Narue Apr 11th, 2005 9:33 am
Re: Can Someone please check my project & comment/tips
 
>void main()
Wrong, main returns int.

>gets(vehicle.V_RegNo);
Wrong, gets can never be made safe. Use fgets on stdin instead.

>fflush(stdin);
Wrong, fflush is only defined for output streams. stdin is an input stream. The equivalent correct code is:
int ch;
while ( ( ch = getchar() ) != EOF && ch != '\n' )
  ;
Everything else is tolerable. It could be made better, but that would require a very lengthy post on my part, and I lack the time to do it properly.

byte_me Apr 12th, 2005 4:54 am
Re: Can Someone please check my project & comment/tips
 
Thank you for taking the time to go through it and for the tips I'll continue to persivere again thanks.

byte_me Apr 12th, 2005 8:41 am
Re: Can Someone please check my project & comment/tips
 
What Other limitations can you find?

Narue Apr 12th, 2005 9:12 am
Re: Can Someone please check my project & comment/tips
 
Your main is a tad long. You could easily modularize that into several smaller functions. It would make understanding how your program works much easier.

byte_me Apr 13th, 2005 5:24 am
Re: Can Someone please check my project & comment/tips
 
As opposed to using a switch statement would you suggest sepperate functions for each case?

Narue Apr 13th, 2005 9:13 am
Re: Can Someone please check my project & comment/tips
 
You could still use a switch, but each case would call a function instead of have such large blocks of code:
switch ( choice ) {
case '1':
  add_vehicle();
  break;
case '2':
  modify_vehicle();
  break;
case '3':
  remove_vehicle();
  break;
case ESC:
  end_program();
  break;
default:
  error_scr("INVALID CHOICE!",2);
  break;
}
Not only is that shorter and easier to grasp at a glance, the code is self documenting. You can understand what's going on without a slew of comments.

byte_me Apr 14th, 2005 1:55 pm
Re: Can Someone please check my project & comment/tips
 
Thanks I'll give it a try - will speak soon


All times are GMT -4. The time now is 11:16 pm.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC