Shaokang's Blog

This is a program to organize computer’s usage using C99 language with a command line interface. It uses malloc to allocate information, and has a shell interaction interface. See more about its functionality by clicking read more.

This program is done in a pretty early stage. I didn’t officially learn C at that time. So, most of stuff are based on self-learning and it might have certain problems, like efficiency, possible memory leaking, some unconverted floating point number out of flow.

Designed functions:

(1) Input function: input the student number, class, name and computer start time. Program would provide multiple ways to ask for the input, batch input could accept multiple lines information that follows certain format. The name is designed to accept UTF-8 characters and it is demoed as using UTF-8 characters.

(2) Calculation function: calculate the cost of each student off the computer, 1 yuan per hour.

(operation cost = operation time * 1.0/h, less than one hour is calculated as one hour)

(3) Query function: according to the conditions (class, student number, name) to display the student’s computer time.

(4) Display of machine usage (the display mode is not limited, but it should be clear at a glance)

Interactions:

Basically, it is a command line program (shell like) that is able to interact by typing the corresponding information. You have the following choices at each run:

1
2
3
4
5
6
7
8
Usage:
Type 's' to show all avaliable status.
Type 'o' for student's leave.
Type 'f' to find.
Type 'p' to show all computers.
Type 'a' for student's arrive.
Type 'h' for help.
Type 'q' for quit.

Different function will have different subcommand, like f will ask you to find by class, student number, or name. And a will ask you for batch adding or add a single one.

Features

  • Built with C99, most of function are as low as I could, like operate on memory level. So, it should be efficient in memory usage.
  • Using low level comparison, like bitwise, in the program. So, it is precise.
  • Have batch add feature, if the user put a serious of data in one time, it is able to import all data once. This function is for implementing adding and saving to file in the future.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <time.h>
#include <math.h>

/*
NEED FIX:
1.wrong message catch
2.read from file
3.Time can only be 1970-1-1 -- 2030-1-1
4.class_num type has limited fit
5.offline should check first
*/

typedef unsigned long long u64;
typedef unsigned int u32;
typedef unsigned short u16;

typedef struct {
u16 index;
u32 class_num;
time_t start_time; //save definite time. From 1970-1-1 REMINDER: THIS IS FINAL STORED ABSOLUTE TIME.
time_t end_time;
u64 stu_id;
u16 flag;
char *name;
}data;
void Show_ava();

int len_data = 60;
data *tt[60];
#define CMD_BUFFER_LEN 80


int ceil_altenate(double a){
int g=(int)a;
if((a-g)>0) return (int)(a+1);
return (int)a;
}

//use money rule to calculate money need to charge
//this function only calculate, it will not modify any value in the struct.
int charge(u16 index){
time_t end;
time(&end);
if(!tt[index]->start_time) return 0;
if(!(tt[index]->flag)) return ceil_altenate(((double)(end-tt[index]->start_time)/3600.0));
return ceil_altenate(((double)(tt[index]->end_time-tt[index]->start_time)/3600.0));
}

//print only one object
void print_one(u16 i) {
if (!((i < len_data)&(i >= 0))) {
printf("Invalid!!!\n");
}else if(!tt[i]->start_time){
printf(" | %2d | %-6s | %5d | %12lld | %04d-%02d-%02d %02d:%02d:%02d |", tt[i]->index + 1, tt[i]->name, tt[i]->class_num, tt[i]->stu_id,
0, 0, 0, 0, 0, 0);
printf("%04d-%02d-%02d %02d:%02d:%02d | %2d | %d |\n",0, 0, 0, 0, 0, 0,charge(tt[i]->index), tt[i]->flag);
}else if (!(tt[i]->flag)) {
struct tm *ptminfo_start=(struct tm *)malloc(sizeof(struct tm *));
ptminfo_start=localtime(&tt[i]->start_time);
printf(" | %2d | %-6s | %5d | %12lld | %02d-%02d-%02d %02d:%02d:%02d |",tt[i]->index+1,tt[i]->name,tt[i]->class_num,tt[i]->stu_id,
ptminfo_start->tm_year + 1900, ptminfo_start->tm_mon + 1, ptminfo_start->tm_mday,
ptminfo_start->tm_hour, ptminfo_start->tm_min, ptminfo_start->tm_sec);
//free(ptminfo_start);
time_t end;
struct tm *ptminfo = (struct tm *)malloc(sizeof(struct tm *));
time(&end);
ptminfo=localtime(&end);

printf("%02d-%02d-%02d %02d:%02d:%02d | %2d | %d |\n",
ptminfo->tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday, ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec,
charge(tt[i]->index),tt[i]->flag);
//free(ptminfo);
}else{
struct tm *ptminfo_start = (struct tm *)malloc(sizeof(struct tm *));
ptminfo_start=localtime(&tt[i]->start_time);

printf(" | %2d | %-6s | %5d | %12lld | %02d-%02d-%02d %02d:%02d:%02d |",tt[i]->index+1,tt[i]->name,tt[i]->class_num,tt[i]->stu_id,
ptminfo_start->tm_year + 1900, ptminfo_start->tm_mon + 1, ptminfo_start->tm_mday,
ptminfo_start->tm_hour, ptminfo_start->tm_min, ptminfo_start->tm_sec);
//free(ptminfo_start);
struct tm *ptminfo = (struct tm *)malloc(sizeof(struct tm *));
ptminfo=localtime(&tt[i]->end_time);

printf("%02d-%02d-%02d %02d:%02d:%02d | %2d | %d |\n",
ptminfo->tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday, ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec,
charge(tt[i]->index),tt[i]->flag);
// free(ptminfo);
}
}

/*Beginning of the finding part*/
//strcmp() : compare two string with case sensitive
void Find_class(u32 cla){
int i;
u16 statu = 1;
//print header
printf(" | #. | Name | Class | Student ID | Start Time | End Time | Charge | Flag |\n");
for(i=0;i<len_data;i++){
if(!(tt[i]->class_num ^ cla)){
statu=0;//Founded
print_one(i);
}
}
if(statu) printf(" |No such catalog!\n");
}

void Find_name(char *nam){
int i;
u16 statu = 1;
//print header
printf(" | #. | Name | Class | Student ID | Start Time | End Time | Charge | Flag |\n");
for(i=0;i<len_data;i++){
if(!strcmp(tt[i]->name,nam)){//This will return the difference between them(Not true means no difference!!!)s
statu=0;//Founded
print_one(i);
}
}
if(statu) printf(" |No such catalog!\n");
}

void Find_stu_id(u64 id){
int i;
u16 statu = 1;
//print header
printf(" | #. | Name | Class | Student ID | Start Time | End Time | Charge | Flag |\n");
for(i=0;i<len_data;i++){
if(!(id ^ tt[i]->stu_id)){
statu=0;//Founded
print_one(i);
}
}
if(statu) printf(" |No such catalog!\n");
}
/*End of finding part.*/

/*Begining of sub-add part*/

//use avaliable computers right now. let student choose which computer. Use loop & flag.
//Add a student and start time calculation.
//Use current system time as the begining time.
void add_stu(){
printf("Now, we are going to guide you to add a record...\nHere are avaliable status of seats right now:\n");
Show_ava();
int statu=1;
u16 No;
do{
if(statu){
printf("Choose the one you prefer(type the No. of the seat):");
}else{
printf("Sorry. There is somebody here. Please choose another seat:");
}
statu=0;
scanf(" %hd",&No);
No--;
while (!((No < len_data)&(No >= 0))) {
printf("Invalid No. Type again:");
scanf(" %hd", &No);
No--;
}
}while(!(tt[No]->flag));
getchar();
printf("Next, we need some basic information of you...\nPlease type your class number:");
u32 No_c;
scanf(" %d",&No_c);
getchar();
printf("Please type your name:");
char *na=(char *)malloc(sizeof(char *)+10);
scanf("%s",na);
printf("Please type your student id:");
u64 stu;
scanf(" %lld",&stu);
time_t rawtime;
time(&rawtime);
//to main part to add
tt[No]->flag=0;
tt[No]->index=No;
tt[No]->stu_id=stu;
tt[No]->class_num=No_c;
tt[No]->start_time=rawtime;
tt[No]->end_time=0;
//printf("%x\n",&tt[No]->name);
//printf("Before:tt[No]->name:%x,na:%x\n",tt[No]->name,na);
//free(tt[No]->name);
tt[No]->name=na;
//printf("After:tt[No]->name:%x,na:%x\n",tt[No]->name,na);
printf("Sucessfully add!\n");
//free(ha);
}

//use when import data
void add_batch(){
printf("<--Description here-->\nBatch import format: No. class student-id name.\nPlease re-enter for two times after finished to make sure you don't have any more data.\nFor example:1 1507 201540070107 aaa\n");
getchar();
int success=0;
int fail=0;
short int No=0;
int No_c=0;
long long int stu=0;
char cmd_buffer[80];
char *read_success;
read_success = fgets(cmd_buffer, 80, stdin);
long long int bak=1;
while(!(read_success==NULL)){
char *na=(char *)malloc(sizeof(char *)+10);
sscanf(cmd_buffer, " %hd %d %lld %s ", &No,&No_c,&stu,na);
if(bak==stu) break;
//printf(" %hd %d %lld %s ------\n", No,No_c,stu,na);
No--;
if(!((No<len_data)&(No>=0))){
printf("No such computer.\n");
fail++;
}else if(!(tt[No]->flag)){
printf("Sorry, somebody is already here.\n");
fail++;
}else{
time_t rawtime;
time(&rawtime);
tt[No]->flag=0;
tt[No]->index=No;
tt[No]->stu_id=stu;
tt[No]->class_num=No_c;
tt[No]->start_time=rawtime;
tt[No]->end_time=0;
tt[No]->name=na;
success++;
printf("Sucessfully add!\n");
}
read_success = fgets(cmd_buffer, 80, stdin);
bak=stu;
}
printf("Success:%d,fail:%d,success rate:%.2f%%\n",success,fail,((double)success/(double)(success+fail))*100);
}

/*End of sub-add part*/


/*Begining of the function part*/


void add(){
printf("Type 'b' to add by batch.\nType 'g' to add with guidence.\nPlease type:\n");
char a;
scanf("%c",&a);
fflush(stdin);
switch(a){
case 'b': case 'B':
add_batch();
break;
case 'g': case 'G':
add_stu();
break;
default:
printf("Wrong option.Type 'h' for help.\n");
break;
}
}

//print out all computer, nomatter in use or not in use. And also student detail information
void print_all(){
printf(" | #. | Name | Class | Student ID | Start Time | End Time | Charge | Flag |\n");
int i;
for(i=0;i<len_data;i++) print_one(i);
}

//a main find function, which will help user choose a specific find function.
void Find(){
printf("Type 'c' to find by class.\nType 'n' to find by name.\nType 's' to find by student id.\nPlease type:\n");
char a;
char *b = (char *)malloc(sizeof(char *) + 10);
scanf("%c",&a);
fflush(stdin);
switch(a){
case 'c': case 'C':
printf("Type message:");
u32 gh;
scanf(" %d",&gh);
getchar();
Find_class(gh);
break;
case 'n': case 'N':
printf("Type message:");
scanf("%s",b);
getchar();
Find_name(b);
free(b);
break;
case 's': case 'S':
printf("Type message:");
u64 gha;
scanf(" %lld",&gha);
getchar();
Find_stu_id(gha);
break;
default:
printf("Wrong option.Type 'h' for help.\n");
break;
}
}

//delete student who are no longer in use. Set flag to 1 and end time to current
void offline(){
printf("Type No. of computer:");
u16 u;
scanf(" %hd",&u);
u--;
time_t rawtime;
time(&rawtime);
tt[u]->flag=1;
tt[u]->end_time=rawtime;
}

//Print out avaliable computer.
//When all computers are in use, show no avaliable
void Show_ava(){
int i;
u16 statu=0;
printf("<--Avaliable status-->\n1--Avaliable 0--Unavaliable\n");
printf("|---------|---------|---------|---------|---------|\n");
for(i=0;i<len_data;i++){
if((len_data-i)<5){statu=1; break;}
printf("| No.%2d | No.%2d | No.%2d | No.%2d | No.%2d |\n",(i+1),(i+2),(i+3),(i+4),(i+5));
printf("| %d | %d | %d | %d | %d |\n",tt[i]->flag,tt[i+1]->flag,tt[i+2]->flag,tt[i+3]->flag,tt[i+4]->flag);
printf("|---------|---------|---------|---------|---------|\n");
i+=4;
}
if(statu){
printf("|---------|---------|---------|---------|---------|\n");
int temp = i;
for(;i<len_data;i++){
printf("| No.%2d ",(i+1));
}
printf("|\n");
i = temp;
for(;i<len_data;i++){
printf("| %d ",tt[i]->flag);
}
printf("|\n");
}
}

/*End of function part*/




/*System running part*/

void execute_help(){
printf("Usage:\n\tType 's' to show all avaliable status.\n\tType 'o' for student's leave.\n\tType 'f' to find.\n\tType 'p' to show all computers.\n\tType 'a' for student's arrive.\n\tType 'h' for help.\n\tType 'q' for quit.\n");
}

//deliver to specific function
int execute_main(char cmd_char){
switch(cmd_char){
case 's': case 'S': Show_ava(); break;
case 'o': case 'O': offline(); break;
case 'f': case 'F': Find(); break;
case 'p': case 'P': print_all(); break;
case 'a': case 'A': add(); break;
case 'h': case 'H': execute_help(); break;
case 'q': case 'Q': {
int u=0;
for(u=0;u<len_data;u++){
//free(tt[u]->name);
free(tt[u]);
}
exit(0);
break;
}
default: printf("Wrong option.Type 'h' for help.\n"); break;
}
return 1;
}
/*End of system running part*/

int run(){
char cmd_char;
char cmd_buffer[CMD_BUFFER_LEN];
char *read_success;
read_success = fgets(cmd_buffer, CMD_BUFFER_LEN, stdin);
if (read_success == NULL) {
return 1;
} else if (sscanf(cmd_buffer, " %c", &cmd_char) == 1) {
fflush(stdin);
execute_main(cmd_char);
} else {
fflush(stdin);
return 1;
}
fflush(stdin);
return 1;
}

//Program will initialize all struct. Assume 60 computers at first. Users can expand it when running by type e.
int main(int argc, char *argv[]){
int i;
for(i=0;i<len_data;i++){
//initialize part
tt[i]=(data *)malloc(sizeof(data)+10);
tt[i]->flag=1;
tt[i]->index=i;
tt[i]->stu_id=0;
tt[i]->class_num=0;
tt[i]->start_time=0;
tt[i]->end_time=0;
tt[i]->name=(char *)malloc(sizeof(char *)+10);
char *na = (char *)malloc(sizeof(char *) + 10);
na = " ";
tt[i]->name = na;
}

char *prompt = "$> ";
printf("Management Application. Author:\n<--Description part-->\n");
execute_help();
printf("%s",prompt);
while(run()){
printf("%s",prompt);
fflush(stdin);
}

return 0;
}

 Comments