**Review .h include needs** Do not rely on other code to include the files for a given .c, .h file. `set.h` needs `<stdio.h>` for `FILE`. `set.h` needs TBD for `Pair`. `get.h` needs `<time.h>` for `time_t`. `get.h` does not need `<stdlib.h>`. `set.c` should include `"set.h"`, first. **Simplify/improve `compareString()`** ``` int compareString(const char* a, const char* b) { int cmp = strncmp(a,b, 2); if (cmp < 0) return 1; if (cmp > 0) return 2; return 0; } ``` Perhaps re-write calling code to use `strncmp()` result directly? **Wrong use of `strncpy()`** Code uses `strncpy()` to prevent overrun, yet risks failing to form a _string_. ``` char command[10]; strncpy(command, argv[1], 10); // BAD as `command` may now lack a null character ``` `snprintf(command, sizeof command, "%s", argv[1]);` is better. Good compilers will emit efficient code. Even this lacks error reporting. I'd write a helper function for this as program arguments can be quite wild. Something like: ``` char *my_strcpy(size_t sz, char dest[sz], char *source) { if (strlen(source) >= sz) { fprintf(stderr, "Destination buffer size [%zu] too small for <%s>.\n", sz, source); exit(EXIT_FAILURE); } return strcpy(dest, source); } ``` **Avoid naked magic number** // Add #define TIME_BUF_YMDHMS_SZ 50 // char buf[50]; char buf[TIME_BUF_YMDHMS_SZ]; struct tm *ts = localtime(&time); // strftime(buf, 50, "%Y-%m-%d %H:%M:%S", ts); strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", ts); With error checking: #define TIME_YMDHMS_FMT "%Y-%m-%d %H:%M:%S" #define TIME_BUF_YMDHMS_SZ (sizeof TIME_YMDHMS_FMT + 6 * 11/* typical longest int string */) char buf[TIME_BUF_YMDHMS_SZ]; struct tm *ts = localtime(&time); if (ts == NULL) { TBD_handle_error(); } if (strftime(buf, sizeof buf, TIME_YMDHMS_FMT, ts) == 0) { TBD_handle_error(); }