Создание программы, которая будет следить за посещаемостью - C (СИ)
Формулировка задачи:
В общем, нужно создать программу, которая будет фиксировать посещаемость.
Что это значит: у нас есть машины, которые контролируют вход и выход работников какого-нибудь офиса. То есть, у работника есть карточка, по которой он заходит в офис. Машин может быть несколько, можно пройти через любой из них. Каждая создает протокол log, в который записывается время (час:минута:секунда) входа и выхода и ID сотрудника. Программа возьмет на вход эти данные.
Входом в программу являются log, который содержит информацию двух типов:
+ h:m:s id
- h:m:s id
+ означает, что сотрудник вошел в здание, - означает что сотрудник вышел из здания. Данные log расположены в порядке возрастания, кроме того, время не повторяется (пройти датчик занимает по меньшей мере 1 с).
так как машин может быть много, то наша программа возьмет logи со всех машин:
log_snimace_1
#
log_snimace_2
#
...
#
log_snimace_N
Logи содержат записи отдельных машин, как показано выше. Так же Logи машин могут быть и пустыми(если через них никто не проходил в течение дня).
Программа сначала проконтролирует параметры входа. Если все хорошо, то программа выпишет работника (работников) дня, которые отработали наибольшее количество часов за день. Работников программа выпишет через запятую и в порядке возрастания. Заодно программа напишет и количество часов проработанных этими лучшими работниками.
Также, программа должна смотреть на правильность входа. Если вход не правильный, то программа должна это проанализировать, написать о том что вход не правильный и закончить свою работу. За неправильный вход считается:
неправильный формат написания в Log
не числовой формат ввода, время не укладывается в рамки от 0:00:00 до 23:59:59
число ID не соответствует рамкам от 1 до 100000
Log пустой(никто не приходил и не уходил)
Log не выполняет последовательность записи входа и выхода(то есть время должно быть возрастающим)
работник, который внутри приходит и работник, который снаружи, выходит
работник внутри остается в здании больше чем 23:59:59
один и тот же работник в одно и тоже время использовал несколько машин
примеры работы:
Zaznamy o dochazce:
+ 8:00:00 100
+ 8:50:00 105
- 9:30:00 100
- 18:20:00 105
- 19:00:00 100
#
- 17:00:00 100
+ 18:00:00 100
#
#
+ 8:00:00 66
+ 9:00:00 200
+ 10:00:00 100
- 15:00:00 200
- 17:30:00 66
Nejdelsi pracovni doba: 9:30:00
Pracovnici dne: 66, 100, 105
Zaznamy o dochazce:
+ 8:00:00 20
+ 9:30:00 30
- 15:00:00 20
- 16:00:00 30
Nejdelsi pracovni doba: 7:00:00
Pracovnik dne: 20
Zaznamy o dochazce:
+ 9:00:00 10
Nespravny vstup.
Zaznamy o dochazce:
* 12:00:00 100
Nespravny vstup.
Zaznamy o dochazce:
+ 10:00:00 100
#
- 10:00:00 100
Nespravny vstup.
Zaznamy o dochazce:
+ 10:00:00 100
#
- 9:00:00 100
Nespravny vstup.
ПС: для чтения входа можно использовать scanf с форматом "%c" и " %c". В чем их отличие?
так же полезной функцией является ungetc().
заранее спасибо за любую помощь. Знаю как использовать
заранее спасибо за любую помощь! по поводу данной программы, знаю как сделать сортировку. Есть идеи для подсчета времени нахождения в здании. Да в принципе по этому заданию есть много идей, но не могу их воплотить в жизнь. Помогите пожалуйста.
Решение задачи: «Создание программы, которая будет следить за посещаемостью»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define START_TIME ( 1417158000 ) #define WORK_TIME ( 8 * 60 * 60 ) #define DELAY_TIME ( 15 * 60 ) enum WORKER_STATE { WS_OUT, WS_IN }; #define MAX_STR_LENGTH ( 32 ) typedef struct WORKER { int cardID; char name[MAX_STR_LENGTH]; } worker_t; #define NUM_WORKERS ( 3 ) typedef struct RECORD { time_t timeStamp; int cardID; int state; } record_t; typedef struct REPORT { const worker_t * pWorker; time_t timeIn; time_t timeOut; } report_t; int create_report(report_t * pRep, const worker_t * pWorker, const record_t * pRecords, const size_t recordsCount) { size_t i; pRep->pWorker = pWorker; for ( i = 0; i < recordsCount; ++i ) { if ( pWorker->cardID == pRecords[i].cardID ) { switch ( pRecords[i].state ) { case WS_OUT : pRep->timeOut = pRecords[i].timeStamp; break; case WS_IN : pRep->timeIn = pRecords[i].timeStamp; break; default : return -1; } } } return 0; } #define SEPARATOR_LINE "+---------+----------------------+------------+------------+------------+" #define HEADER "| card ID | Worker name | Incoming | Outgoing | On place |" void print_report(const report_t * pRep) { char inStr[MAX_STR_LENGTH], outStr[MAX_STR_LENGTH], onplaceStr[MAX_STR_LENGTH]; long onPlace; strftime(inStr, MAX_STR_LENGTH, "%H:%M", localtime(&(pRep->timeIn))); strftime(outStr, MAX_STR_LENGTH, "%H:%M", localtime(&(pRep->timeOut))); onPlace = (long)(pRep->timeOut - pRep->timeIn); sprintf(onplaceStr, "%u:%02u", onPlace / 60 / 60, onPlace / 60 % 60); printf("| %-7d | %-20s | %-10s | %-10s | %-10s |\n", pRep->pWorker->cardID, pRep->pWorker->name, inStr, outStr, onplaceStr); } int shuffle(const void * a, const void * b) { return rand() - rand(); } int reports_by_name(const void * a, const void * b) { return strcmp(((report_t*)a)->pWorker->name, ((report_t*)b)->pWorker->name); } int reports_by_incoming(const void * a, const void * b) { return (int)(((report_t*)a)->timeIn - ((report_t*)b)->timeIn); } int reports_by_outgoing(const void * a, const void * b) { return (int)(((report_t*)a)->timeOut - ((report_t*)b)->timeOut); } int reports_by_onplace(const void * a, const void * b) { report_t * pA = (report_t*)a; report_t * pB = (report_t*)b; return (int)((pA->timeOut - pA->timeIn) - (pB->timeOut - pB->timeIn)); } int main(void) { worker_t workers[NUM_WORKERS] = { { 1, "Ivanov" }, { 2, "Petrov" }, { 3, "Sidorov" } }; report_t reports[NUM_WORKERS]; record_t records[NUM_WORKERS * 2]; int i, rec = 0; time_t currentTime = START_TIME; srand(time(NULL)); /* Пришли на работу */ qsort(workers, NUM_WORKERS, sizeof(worker_t), shuffle); for ( i = 0; i < NUM_WORKERS; ++i ) { currentTime += rand() % DELAY_TIME; records[rec].cardID = workers[i].cardID; records[rec].timeStamp = currentTime; records[rec].state = WS_IN; ++rec; } /* Ушли с работы */ currentTime = START_TIME + WORK_TIME; qsort(workers, NUM_WORKERS, sizeof(worker_t), shuffle); for ( i = 0; i < NUM_WORKERS; ++i ) { currentTime += rand() % DELAY_TIME; records[rec].cardID = workers[i].cardID; records[rec].timeStamp = currentTime; records[rec].state = WS_OUT; ++rec; } /* Составили отчёт */ for ( i = 0; i < NUM_WORKERS; ++i ) if ( create_report(&reports[i], &workers[i], records, rec) ) return 1; qsort(reports, NUM_WORKERS, sizeof(report_t), reports_by_name); printf("Sorted by name:\n"); printf("%s\n%s\n%s\n", SEPARATOR_LINE, HEADER, SEPARATOR_LINE); for ( i = 0; i < NUM_WORKERS; ++i ) { print_report(&reports[i]); printf("%s\n", SEPARATOR_LINE); } printf("Press ENTER..."); getchar(); qsort(reports, NUM_WORKERS, sizeof(report_t), reports_by_incoming); printf("Sorted by incoming:\n"); printf("%s\n%s\n%s\n", SEPARATOR_LINE, HEADER, SEPARATOR_LINE); for ( i = 0; i < NUM_WORKERS; ++i ) { print_report(&reports[i]); printf("%s\n", SEPARATOR_LINE); } printf("Press ENTER..."); getchar(); qsort(reports, NUM_WORKERS, sizeof(report_t), reports_by_outgoing); printf("Sorted by outgoing:\n"); printf("%s\n%s\n%s\n", SEPARATOR_LINE, HEADER, SEPARATOR_LINE); for ( i = 0; i < NUM_WORKERS; ++i ) { print_report(&reports[i]); printf("%s\n", SEPARATOR_LINE); } printf("Press ENTER..."); getchar(); qsort(reports, NUM_WORKERS, sizeof(report_t), reports_by_onplace); printf("Sorted by onplace:\n"); printf("%s\n%s\n%s\n", SEPARATOR_LINE, HEADER, SEPARATOR_LINE); for ( i = 0; i < NUM_WORKERS; ++i ) { print_report(&reports[i]); printf("%s\n", SEPARATOR_LINE); } printf("Press ENTER..."); getchar(); return 0; }
Объяснение кода листинга программы
Код представляет собой программу для отслеживания посещаемости работников. Основные действия программы:
- Создание структуры worker_t для хранения информации о работниках.
- Создание структуры record_t для хранения информации о записях посещаемости.
- Создание структуры report_t для хранения информации о отчетах по работникам.
- Создание функции create_report для формирования отчета по работнику на основе записей посещаемости.
- Создание функции print_report для вывода отчета по работнику.
- Создание функции shuffle для перемешивания элементов при сортировке.
- Создание функции reports_by_name для сортировки отчетов по имени работника.
- Создание функции reports_by_incoming для сортировки отчетов по времени прихода на работу.
- Создание функции reports_by_outgoing для сортировки отчетов по времени ухода с работы.
- Создание функции reports_by_onplace для сортировки отчетов по времени пребывания на работе.
- Создание массива workers с информацией о работниках.
- Создание массива records с записями посещаемости.
- Создание массива reports для хранения отчетов по работникам.
- Имитация процесса работы работников с помощью функции rand().
- Вывод отчетов по работникам в различных сортировках.
Переменные:
- START_TIME - начальное время.
- WORK_TIME - время работы.
- DELAY_TIME - задержка между приходом и уходом с работы.
- MAX_STR_LENGTH - максимальная длина строки.
- NUM_WORKERS - количество работников.
- SEPARATOR_LINE - строка-разделитель.
- HEADER - заголовок таблицы.
- onplaceStr - строка для хранения информации о времени пребывания на работе. Примечание: код не тестировался и может потребовать доработки.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д