Friday, 23 November 2012

The complete Program in C, but without the file tree.
The files needed to run this program include a folder in the same directory as the program called "docs". In this folder, create one textfile per employee. THe name of the textfile may be anything random, as what counts is the first line of the textfile, which must be the employees full name.
After you've saved and closed the textfile, run the program, and it will take over from that point onwards. The program will read the name in the file and add the employees times at work. To add more employees, just create new textfiles in the docs folder, to delete employees, just cut or delete the textfile from the docs folder.

#define ANNOUNCE printf("Line %d\n", __LINE__);
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <memory.h>


char fileNameToBeOpened[50] = " ";    // Name of file to be opened
char oldFile[365];                       // The old file, one place for each day of the year
char** fileNames;                     // A pointer to filenames.

int numberOfEmployees = 0;              // Holds the number of employees found
time_t timeNow;                          // Needed to calculate the time
double timeElapsed;
struct tm *now ;

char buffer[100] ;

struct employee             //this structure represents one employee
{
  int present;                 //is 0 if the present is away and 1 if present
  char name[50];             //holds the name of this employee
  int startTime;            //holds the starttime for that session
  int startTimes[364];        //holds the start timesof this employee
  int timesPresent[364];    //holds the times the employee was present
};

struct employee employeeArray[20];     //an array of employee structures

//sets the employees status to the new status
void changeStatus(int i)
{
    if(employeeArray[i].present == 1)
    {
        employeeArray[i].present = 0;

        //calculate time elapsed between logging in and logging out
        long currentTime = time (NULL);
        timeElapsed = currentTime - employeeArray[i].startTime;

        //add elapsed time to the file
        char fullFilePath[150] = "docs/";
        strcat(fullFilePath, fileNames[i]);

        FILE *newfile = fopen(fullFilePath, "a"); //open the specified file

        fprintf(newfile,"%d\t", employeeArray[i].startTime); //write current time to new file
        fprintf(newfile,"%lf", timeElapsed); //write elapsed time to new file   
        fprintf(newfile,"\n"); //a line break to the new file

        fclose(newfile); //close and save the file new file

        //get the time in a human readbale format
           timeNow = timeElapsed ;
           int hoursAtWork = timeElapsed/3600; //get the number of hours the worker worked for
           timeElapsed = timeElapsed - (hoursAtWork*3600); //subtract the hours from the time

           int minutesAtWork = timeElapsed/60; //get minutes employe worked for
           timeElapsed = timeElapsed - (minutesAtWork*60); //subtract minut es from time, leaving seconds

           printf("\n---------------------------------------------------");
           printf("\n\t Employee was at work for: %d:%d:%d", hoursAtWork, minutesAtWork, (int)timeElapsed);
    }
    else
    {
        employeeArray[i].present = 1;
        //insert the current time as start time
        employeeArray[i].startTime = time (NULL);
    }
}

//reads a single employee file into memory
void readEmployeeFile()
{
    int i;                          //for for loop
    int x         = 0;               //for small nested loops
    int line      = 0;
    int nameFound = 0;             //set this to 1 if the name is found already (in line 1)
    int tempPresentTime;
    int tempStartTime;
    char tempName[50];
    char tempStartTimeArray[50];   //needed to take the number from the file
    char tempPresentTimeArray[50];   

    int whichTime = 0; //holds which time we read in, 0 for starttime, 1 for timePresent

    //open every single file of every employee in the array
    for(i = 0; i < numberOfEmployees; ++i)
    {
        line      = 0;
        x         = 0;
        nameFound = 0;    //this holds weather the name in the first line has been found

        char fullFilePath[150] = "docs/";
        strcat(fullFilePath, fileNames[i]);

        FILE *file = fopen(fullFilePath, "r"); //open the specified file

        if ( file != NULL ) //check if the file specified exists
        {
            char ch;        //this variable holds the value of one char from the file

            while ( (ch = fgetc(file)) != EOF ) //take char by char from file
            {
                if(nameFound == 0)
                {
                    if(ch != '\n') //add the char to the name of the employee
                    {
                        tempName[x] = ch;
                        tempName[x+1] = '\0';
                        x++;
                    }
                    else //reading in name is completed
                    {
                        x = 0;
                        while(x < 50)
                        {
                            employeeArray[i].name[x] = tempName[x];
                            x++;
                        }
                        nameFound = 1;
                        x = 0;
                    }
                }
                else
                {   
                    //we're reading the rest of the file, which is only the times
                    if(ch == '\n') //if a new line is read
                      {
                          //we assume we now have two ready variables holding the values from the line of the file
                          tempPresentTime = atoi(tempPresentTimeArray);
                          //printf("Employee %s\n", employeeArray[i].name);

                          employeeArray[i].startTimes[line] = tempStartTime;
                          //printf("Temp Start Time: %d\n", employeeArray[i].startTimes[line]);

                          employeeArray[i].timesPresent[line] = tempPresentTime;
                          //printf("Temp present Time: %d\n", employeeArray[i].timesPresent[line]);

                          x         = 0;  //reset
                          whichTime = 0;     //reset
                          line++;            //presume to next line
                      }
                      else
                      {
                          if(ch == '\t')
                          {
                              whichTime = 1; //we now take the time Present

                              //convert the start time to a integer
                              tempStartTime = atoi(tempStartTimeArray);
                              x             = 0;    //reset to start second variable array at 0
                          }
                          if(whichTime == 0)
                          {
                              tempStartTimeArray[x] = ch;
                          }
                          else
                          {
                              tempPresentTimeArray[x] = ch;
                          }
                          x++;
                      }
                }
            }
            fclose(file); //close and save the file old file
        }
        else
        {
            printf("File could not be opened!\n");
            printf("FileName to be opened: %s\n", fullFilePath);
        }
    }
}

//prints all the times found from the file
void printTimes()
{
    int i;
    int j;
    int hoursAtWork;
    int minutesAtWork;

    printf("Times Employees were at work:\n");

    for(i = 0; i < numberOfEmployees; ++i)
    {
        printf("\n\t%s\n", employeeArray[i].name);
        printf("Time Present: \t\tDate:\n");
        j = 0;   

        while(employeeArray[i].startTimes[j] != 0 || employeeArray[i].timesPresent[j] != 0) //while one still has content
        {
               timeNow = employeeArray[i].startTimes[j] ;
               now = localtime( &timeNow ) ;

               timeElapsed = employeeArray[i].timesPresent[j];

            //get the time in a human readbale format
               hoursAtWork   = timeElapsed/3600;                 //get the number of hours the worker worked for
               timeElapsed   = timeElapsed - (hoursAtWork*3600); //subtract the hours from the time
               minutesAtWork = timeElapsed/60;                   //get minutes employe worked for
               timeElapsed   = timeElapsed - (minutesAtWork*60); //subtract minutes from time, leaving seconds

               printf("%d:%d:%d\t\t\t", hoursAtWork, minutesAtWork, (int)timeElapsed);
            printf( "%s" , asctime( now )) ;

            j++;
        }
    }
}

/**
 * A function which returns an array of all user data files.
 *
 * @param  num : Used to return the number of files
 * @return char* to the array that contains the info.
 */
char** listContents(int* num)
{
    DIR * dp;
    dp = opendir("docs");   // The dir where user files will be located.
    struct dirent *dirp;
    char* fileName;

    int count = 0;

    if(dp)
    {
        // Just count how many files are in the dir.
        while((dirp = readdir(dp)) != NULL)
        {
            count++;
        }

        // Remove 2 as, the dir lists '.' and '..' as files.
        count -= 2;
       
        // CHANGE: Use num to return the count
        *num = count;

        // CHANGE : Have to reset the dir (or we could make a new one)
        rewinddir(dp);
       
        // So if actually found any files.
        if(count > 0)
        {
            // Array of pointers to store the file names.
            char* userFiles[count];

            // Restart the read again, but now read the info in the array.
            int i=0;

            while((dirp = readdir(dp)) != NULL)
            {
                fileName = dirp->d_name;

                // CHANGE: You can't use sizeof to get the length of a string, only an array. Use strlen
                if((fileName[0] == '.' && fileName[1] == '.' && strlen(fileName) == 2) || (fileName[0] == '.' && strlen(fileName) == 1))
                {
                    // Do nothing as reading '.' or '..' dirs.
                }
                else
                {
                    // CHANGE: Make a copy of fileCopy. Note we use strlen and strcpy
                    // as we are copying strings
                    char* fileCopy = malloc(strlen(fileName) + 1);
                    strcpy(fileCopy, fileName);
                    // Add the file to the array.
                    userFiles[i] = fileCopy;
                    i++;
                }
            }
           
            // CHANGE: Make a copy of userFiles.
            // note the use of malloc / memcpy.
            // NOTE: This will not recopy the filenames which this array points to.
            char** userFilesCopy = malloc(count * sizeof(char*));
            memcpy(userFilesCopy, userFiles, count * sizeof(char*));
           
            return userFilesCopy;
        }
        else
        {
            // No files found, return null.
            return NULL;
        }
    }
    else
    {
        // No files found, return null.
        return NULL;
    }
}

void mainMenu()
{
    int i;   
    int user_Choice = 0;
    int continueLoop = 1;
    while(continueLoop == 1)
    {
        printf("\n---------------------------------------------------\n\n");
        printf("AC21008, Group 11 \n\tClock Main Menu\n\n");
        i = 0; //holds count of the number of employees we have
        for(i = 0; i < numberOfEmployees; i++)
        {
            if(employeeArray[i].present == 1)
            {
                printf("%d) %s \tis in.\n", i+1, employeeArray[i].name);
            }
            else
            {
                printf("%d) %s \tis out.\n", i+1, employeeArray[i].name);
            }
        }

        printf("\nSelect the employees number, to check in or out.\n");
        printf("Select 88, to print times employees were at work\n");
        printf("Select 99, to Quit\n");
        printf("\n--> ");

        //get user input
        scanf("%d", &user_Choice);
        if((user_Choice >= 1 && user_Choice <= numberOfEmployees+1) || user_Choice == 99 || user_Choice == 88) //allow chars or digits only
        {
            // Check if a selected choice is a user.
            if((user_Choice-1) >= 0 && (user_Choice-1) < numberOfEmployees)
            {
                // Clear the screen.
                system("clear");
                changeStatus(user_Choice-1);
            }
            //the other menu choices
            if(user_Choice == 88) // list all times of employees
            {
                //get the latest data from the file
                readEmployeeFile();
                //print the data
                printTimes();
            }
            if(user_Choice == 99)
            {
                printf("\nBye bye!\n");
                continueLoop = 0;
            }                 
        }
        else
        {
            printf("Please select a valid choice!\n");
        }

        if (fgets(&user_Choice, sizeof(&user_Choice), stdin)) //this line clears the buffer
        {
          //we could print the last character in the input, but we dont
        }
    }
}

int main()
{
    // Clear the screen.
    system("clear");
    // Create an array of all the employees.
    fileNames = listContents(&numberOfEmployees);
    // Read all employee files and load in data.
    readEmployeeFile();
    mainMenu();
    return 1;
}

No comments:

Post a Comment