/* memo: program to record personal memos and display them in * the terminal. Memos saved in conf/all_memos.txt */ #include #include #include #define MAX_MEMOS 100 //max number of memos #define MAX_T 100 //max length of title #define MAX_B 3000 //max length of body #define D '#' struct memo { char title[MAX_T]; char body[MAX_B]; }; struct memo memos[MAX_MEMOS]; FILE *all_memos; int main(int argc, char *argv[]) { int read_t_b_between_d(FILE*, char*, char*, char); void print_titles_to_screen(int); int print_n_take_opts(int); void print_memo_to_screen(int); void clear(); int compose_memo(int); void save_memos(FILE*, int); int delete_memo(FILE*, int, int); int read_memos(FILE*); int m_count; // memo count, total number of memos int selected; /* check if conf directory exists. if not, create it. */ struct stat st = {0}; if (stat("conf", &st) == -1){ mkdir("conf", 0700); } /* create conf/all_memos.txt in case it does not already exist */ char *command_1 = "touch conf/all_memos.txt"; system(command_1); m_count = read_memos(all_memos); if (m_count == 0){ clear(); printf("\n\n\tMemo Wizard\n\n\tCreate your first memo.\n"); m_count = compose_memo(m_count); save_memos(all_memos, m_count); clear(); } while((selected = print_n_take_opts(m_count))){ if (selected == m_count + 1){ clear(); m_count = compose_memo(m_count); save_memos(all_memos, m_count); clear(); }else if (selected > 0 && selected <= m_count) print_memo_to_screen(selected); else if (selected * -1 > 0 && selected * -1 <= m_count){ selected *= -1; m_count = delete_memo(all_memos, selected, m_count); read_memos(all_memos); }else ; } clear(); printf("\nHave a nice day!\n\n"); return 0; } /* read_t_b_between_d: function to read the title and the body from all_memos.txt. title and body * saved between demarker d, which is '#' */ int read_t_b_between_d(FILE *am, char *t, char *b, char d) { char c; while ((c = getc(am)) != d && c != EOF) ; if (c == EOF) return -1; while ((c = getc(am)) != d && c != EOF) *t++ = c; if (c == EOF) return -1; *t = '\0'; while ((c = getc(am)) != d && c != EOF) ; if (c == EOF) return -1; while ((c = getc(am)) != d && c != EOF) *b++ = c; if (c == EOF) return -1; *b = '\0'; return 0; } void print_titles_to_screen(int i) { printf("\n\n\tMemo Wizard\n\n\t"); for (int k = 0; i > 0; i--, k++){ printf("%d. %s ", k+1, memos[k].title); if (((k+1) % 4) == 0) printf("\n\t"); } } /* save memos from struct to all_memos.txt, n = number of memos */ void save_memos(FILE *am, int n){ am = fopen("conf/all_memos.txt", "w"); for (int i = 0; i < n; i++) fprintf(am, "#%s# #%s#\n\n", memos[i].title, memos[i].body); fclose(am); } void clear(){ system("clear"); } /* compose memo saving it to the correct array member and returning the new number of memos */ int compose_memo(int n){ int j = 0; printf("\n\tTitle: "); while ((memos[n].title[j++] = getchar()) != '\n') ; --j; memos[n].title[j] = '\0'; j = 0; printf("\n\n\tCompose memo ['|' to end]\n\n\t"); while ((memos[n].body[j++] = getchar()) != '|') ; --j; memos[n].body[j] = '\0'; ++n; return n; } int print_n_take_opts(int mc){ void clear(); int s; //selection clear(); print_titles_to_screen(mc); printf("\n\n\tEnter a memo number to view it. To compose a new memo,\n" "\tenter the next consecutive number. To delete a memo, enter\n" "\tits number preceded by a minus sign. ['0' to exit] "); scanf("%d", &s); getchar(); return s; } void print_memo_to_screen(int s){ --s; clear(); printf("\n\n\t%s\n\n\t%s\n\n\tPress enter to return to main menu ", memos[s].title, memos[s].body); getchar(); } /* delete_memo: to delete a memo, *am = all_memos, number of memo to delete md, and the total number of * memos = n */ int delete_memo(FILE *am, int md, int n){ am = fopen("conf/all_memos.txt", "w"); for (int i = 0; i < n; i++){ if (i == md-1) ; else fprintf(am, "#%s# #%s#\n\n", memos[i].title, memos[i].body); } fclose(am); return --n; } int read_memos(FILE *am){ am = fopen("conf/all_memos.txt", "r"); int i = 0; while ((read_t_b_between_d(am, memos[i].title, memos[i].body, D) != -1)) ++i; fclose(am); return i; }