重构的过程记录--之利用系统数据库:
代码:
将manjaro的自动桌面bing中的桌面自动备份脚本:cp ~/.cache/plasma_engine_potd/bing ~/bing_`date +%Y%m%d`.jpg
cp ~/.cache/plasma_engine_potd/apod ~/apod_`date +%Y%m%d`.jpg
1 //This is c program code! 2 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 3 * 文档信息: *** :~/WORKM/stutyCode/linuxPrograming/manageDisk/v2/appUi.c 4 * 版权声明: *** :(魎魍魅魑)MIT 5 * 联络信箱: *** :guochaoxxl@163.com 6 * 创建时间: *** :2020年12月14日的上午10:39 7 * 文档用途: *** :数据结构与算法分析-c语言描述 8 * 作者信息: *** :guochaoxxl(http://cnblogs.com/guochaoxxl) 9 * 修订时间: *** :2020年第50周 12月14日 星期一 上午10:39 (第349天) 10 * 文件描述: *** :自行添加 11 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ 12 #define _XOPEN_SOURCE 13 14 #include "cdData.h" 15 16 #define TMP_STRING_LEN 125 /* this number must be larger than the biggest single string in any database structure */ 17 18 19 20 /* local prototypes */ 21 // int command_mode(int argc, char *argv[]); 22 // void announce(void); 23 // menu_options show_menu(const CdcEntry *current_cdc); 24 // int get_confirm(const char *question); 25 // int enter_new_cat_entry(CdcEntry *entry_to_update); 26 // void enter_new_track_entries(const CdcEntry *entry_to_add_to); 27 // void del_cat_entry(const CdcEntry *entry_to_delete); 28 // void del_track_entries(const CdcEntry *entry_to_delete); 29 // CdcEntry find_cat(void); 30 // void list_tracks(const CdcEntry *entry_to_use); 31 // void count_all_entries(void); 32 // void display_cdc(const CdcEntry *cdc_to_show); 33 // void display_cdt(const CdtEntry *cdt_to_show); 34 // void strip_return(char *string_to_strip); 35 36 void announce(void) { 37 printf("\n\nWelcome to the demonstration CD catalog database program\n"); 38 } /* announce */ 39 40 menu_options show_menu(const CdcEntry *cdc_selected) { 41 char tmp_str[TMP_STRING_LEN + 1]; 42 menu_options option_chosen = mo_invalid; 43 44 while (option_chosen == mo_invalid) { 45 if (cdc_selected->catalog[0]) { 46 printf("\n\nCurrent entry: "); 47 printf("%s, %s, %s, %s\n", cdc_selected->catalog, 48 cdc_selected->title, 49 cdc_selected->type, 50 cdc_selected->artist); 51 52 printf("\n"); 53 printf("1 - add new CD\n"); 54 printf("2 - search for a CD\n"); 55 printf("3 - count the CDs and tracks in the database\n"); 56 printf("4 - re-enter tracks for current CD\n"); 57 printf("5 - delete this CD, and all it's tracks\n"); 58 printf("6 - list tracks for this CD\n"); 59 printf("q - quit\n"); 60 printf("\nOption: "); 61 fgets(tmp_str, TMP_STRING_LEN, stdin); 62 switch(tmp_str[0]) { 63 case '1': option_chosen = mo_add_cat; break; 64 case '2': option_chosen = mo_find_cat; break; 65 case '3': option_chosen = mo_count_entries; break; 66 case '4': option_chosen = mo_add_tracks; break; 67 case '5': option_chosen = mo_del_cat; break; 68 case '6': option_chosen = mo_list_cat_tracks; break; 69 case 'q': option_chosen = mo_exit; break; 70 } 71 } 72 else { 73 printf("\n\n"); 74 printf("1 - add new CD\n"); 75 printf("2 - search for a CD\n"); 76 printf("3 - count the CDs and tracks in the database\n"); 77 printf("q - quit\n"); 78 printf("\nOption: "); 79 fgets(tmp_str, TMP_STRING_LEN, stdin); 80 switch(tmp_str[0]) { 81 case '1': option_chosen = mo_add_cat; break; 82 case '2': option_chosen = mo_find_cat; break; 83 case '3': option_chosen = mo_count_entries; break; 84 case 'q': option_chosen = mo_exit; break; 85 } 86 } 87 } /* while */ 88 return(option_chosen); 89 } /* show_menu */ 90 91 int get_confirm(const char *question) { 92 char tmp_str[TMP_STRING_LEN + 1]; 93 94 printf("%s", question); 95 fgets(tmp_str, TMP_STRING_LEN, stdin); 96 if (tmp_str[0] == 'Y' || tmp_str[0] == 'y') { 97 return(1); 98 } 99 return(0); 100 } /* get_confirm */ 101 102 103 int enter_new_cat_entry(CdcEntry *entry_to_update) { 104 CdcEntry new_entry; 105 char tmp_str[TMP_STRING_LEN + 1]; 106 107 memset(&new_entry, '\0', sizeof(new_entry)); 108 109 printf("Enter catalog entry: "); 110 (void)fgets(tmp_str, TMP_STRING_LEN, stdin); 111 strip_return(tmp_str); 112 strncpy(new_entry.catalog, tmp_str, CAT_CAT_LEN - 1); 113 114 printf("Enter title: "); 115 (void)fgets(tmp_str, TMP_STRING_LEN, stdin); 116 strip_return(tmp_str); 117 strncpy(new_entry.title, tmp_str, CAT_TITLE_LEN - 1); 118 119 printf("Enter type: "); 120 (void)fgets(tmp_str, TMP_STRING_LEN, stdin); 121 strip_return(tmp_str); 122 strncpy(new_entry.type, tmp_str, CAT_TYPE_LEN - 1); 123 124 printf("Enter artist: "); 125 (void)fgets(tmp_str, TMP_STRING_LEN, stdin); 126 strip_return(tmp_str); 127 strncpy(new_entry.artist, tmp_str, CAT_ARTIST_LEN - 1); 128 129 printf("\nNew catalog entry entry is :-\n"); 130 display_cdc(&new_entry); 131 if (get_confirm("Add this entry ?")) { 132 memcpy(entry_to_update, &new_entry, sizeof(new_entry)); 133 return(1); 134 } 135 return(0); 136 } /* add_new_CdcEntry */ 137 138 void enter_new_track_entries(const CdcEntry *entry_to_add_to) { 139 CdtEntry new_track, existing_track; 140 char tmp_str[TMP_STRING_LEN + 1]; 141 int track_no = 1; 142 143 if (entry_to_add_to->catalog[0] == '\0') return; 144 printf("\nUpdating tracks for %s\n", entry_to_add_to->catalog); 145 printf("Press return to leave existing description unchanged,\n"); 146 printf(" a single d to delete this and remaining tracks,\n"); 147 printf(" or new track description\n"); 148 149 while(1) { 150 memset(&new_track, '\0', sizeof(new_track)); 151 existing_track = get_CdtEntry(entry_to_add_to->catalog, track_no); 152 if (existing_track.catalog[0]) { 153 printf("\tTrack %d: %s\n", track_no, existing_track.track_txt); 154 printf("\tNew text: "); 155 } 156 else { 157 printf("\tTrack %d description: ", track_no); 158 } 159 fgets(tmp_str, TMP_STRING_LEN, stdin); 160 strip_return(tmp_str); 161 if (strlen(tmp_str) == 0) { 162 if (existing_track.catalog[0] == '\0') { 163 /* no existing entry, so finished adding */ 164 break; 165 } 166 else { 167 /* leaves existing entry, jump to next track */ 168 track_no++; 169 continue; 170 } 171 } 172 if ((strlen(tmp_str) == 1) && tmp_str[0] == 'd') { 173 /* delete this and remaining tracks */ 174 while (del_CdtEntry(entry_to_add_to->catalog, track_no)) { 175 track_no++; 176 } 177 break; 178 } 179 180 /* if we get here then adding or updating track */ 181 strncpy(new_track.track_txt, tmp_str, TRACK_TTEXT_LEN - 1); 182 strcpy(new_track.catalog, entry_to_add_to->catalog); 183 new_track.track_no = track_no; 184 if (!add_CdtEntry(new_track)) { 185 fprintf(stderr, "Failed to add new track\n"); 186 break; 187 } 188 track_no++; 189 } /* while */ 190 } /* enter_new_track_entries */ 191 192 void del_cat_entry(const CdcEntry *entry_to_delete) { 193 int track_no = 1; 194 int delete_ok; 195 196 display_cdc(entry_to_delete); 197 if (get_confirm("Delete this entry and all it's tracks? ")) { 198 do { 199 delete_ok = del_CdtEntry(entry_to_delete->catalog, track_no); 200 track_no++; 201 } while(delete_ok); 202 203 if (!del_CdcEntry(entry_to_delete->catalog)) { 204 fprintf(stderr, "Failed to delete entry\n"); 205 } 206 } 207 } /* del_cat_entry */ 208 209 void del_track_entries(const CdcEntry *entry_to_delete) { 210 int track_no = 1; 211 int delete_ok; 212 213 display_cdc(entry_to_delete); 214 if (get_confirm("Delete tracks for this entry? ")) { 215 do { 216 delete_ok = del_CdtEntry(entry_to_delete->catalog, track_no); 217 track_no++; 218 } while(delete_ok); 219 } 220 } /* del_track_entries */ 221 222 CdcEntry find_cat(void) { 223 CdcEntry item_found; 224 char tmp_str[TMP_STRING_LEN + 1]; 225 int first_call = 1; 226 int any_entry_found = 0; 227 int string_ok; 228 int entry_selected = 0; 229 230 do { 231 string_ok = 1; 232 printf("Enter string to search for in catalog entry: "); 233 fgets(tmp_str, TMP_STRING_LEN, stdin); 234 strip_return(tmp_str); 235 if (strlen(tmp_str) > CAT_CAT_LEN) { 236 fprintf(stderr, "Sorry, string too long, maximum \ 237 %d characters\n", CAT_CAT_LEN); 238 string_ok = 0; 239 } 240 } while (!string_ok); 241 242 while (!entry_selected) { 243 item_found = search_CdcEntry(tmp_str, &first_call); 244 if (item_found.catalog[0] != '\0') { 245 any_entry_found = 1; 246 printf("\n"); 247 display_cdc(&item_found); 248 if (get_confirm("This entry? ")) { 249 entry_selected = 1; 250 } 251 } else { 252 if (any_entry_found) printf("Sorry, no more matches found\n"); 253 else printf("Sorry, nothing found\n"); 254 break; 255 } 256 } 257 return(item_found); 258 } /* find_cat */ 259 260 void list_tracks(const CdcEntry *entry_to_use) { 261 int track_no = 1; 262 CdtEntry entry_found; 263 264 display_cdc(entry_to_use); 265 printf("\nTracks\n"); 266 do { 267 entry_found = get_CdtEntry(entry_to_use->catalog, track_no); 268 if (entry_found.catalog[0]) { 269 display_cdt(&entry_found); 270 track_no++; 271 } 272 } while(entry_found.catalog[0]); 273 (void)get_confirm("Press return"); 274 } /* list_tracks */ 275 276 void count_all_entries(void) { 277 int cd_entries_found = 0; 278 int track_entries_found = 0; 279 CdcEntry cdc_found; 280 CdtEntry cdt_found; 281 int track_no = 1; 282 int first_time = 1; 283 char *search_string = ""; 284 285 do { 286 cdc_found = search_CdcEntry(search_string, &first_time); 287 if (cdc_found.catalog[0]) { 288 cd_entries_found++; 289 track_no = 1; 290 do { 291 cdt_found = get_CdtEntry(cdc_found.catalog, track_no); 292 if (cdt_found.catalog[0]) { 293 track_entries_found++; 294 track_no++; 295 } 296 } while (cdt_found.catalog[0]); 297 } 298 } while (cdc_found.catalog[0]); 299 300 printf("Found %d CDs, with a total of %d tracks\n", 301 cd_entries_found, track_entries_found); 302 (void)get_confirm("Press return"); 303 304 } /* count_all_entries */ 305 306 307 void display_cdc(const CdcEntry *cdc_to_show) { 308 printf("Catalogue: %s\n", cdc_to_show->catalog); 309 printf("\ttitle: %s\n", cdc_to_show->title); 310 printf("\ttype: %s\n", cdc_to_show->type); 311 printf("\tartist: %s\n", cdc_to_show->artist); 312 } /* display_cdc */ 313 314 void display_cdt(const CdtEntry *cdt_to_show) { 315 printf("%d: %s\n", cdt_to_show->track_no, cdt_to_show->track_txt); 316 } /* display_cdt */ 317 318 void strip_return(char *string_to_strip) { 319 int len; 320 321 len = strlen(string_to_strip); 322 if (string_to_strip[len - 1] == '\n') string_to_strip[len - 1] = '\0'; 323 } /* strip_return */ 324 325 326 int command_mode(int argc, char *argv[]) { 327 int c; 328 int result = EXIT_SUCCESS; 329 char *prog_name = argv[0]; 330 331 /* these externals used by getopt************************ 332 extern char *optarg; 333 extern optind, opterr, optopt; ***************************/ 334 335 /************* Neil - getopt() in unistd only if __USE_POSIX2 336 any idea what this means or why? **************************/ 337 while ((c = getopt(argc, argv, ":i")) != -1) { 338 switch(c) { 339 case 'i': 340 if (!database_initialize(1)) { 341 result = EXIT_FAILURE; 342 fprintf(stderr, "Failed to initialize database\n"); 343 } 344 break; 345 case ':': 346 case '?': 347 default: 348 fprintf(stderr, "Usage: %s [-i]\n", prog_name); 349 result = EXIT_FAILURE; 350 break; 351 } /* switch */ 352 } /* while */ 353 return(result); 354 } /* command_mode */
代码:
1 //This is c program code! 2 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 3 * 文档信息: *** :~/WORKM/stutyCode/linuxPrograming/manageDisk/v2/cdAccess.c 4 * 版权声明: *** :(魎魍魅魑)MIT 5 * 联络信箱: *** :guochaoxxl@163.com 6 * 创建时间: *** :2020年12月14日的下午02:40 7 * 文档用途: *** :数据结构与算法分析-c语言描述 8 * 作者信息: *** :guochaoxxl(http://cnblogs.com/guochaoxxl) 9 * 修订时间: *** :2020年第50周 12月14日 星期一 下午02:40 (第349天) 10 * 文件描述: *** :自行添加 11 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ 12 #define _XOPEN_SOURCE 13 14 15 /* The above include may need to be changed to gdbm-ndbm.h on some Linux distributions */ 16 17 #include "cdData.h" 18 19 #define CDC_FILE_BASE "cdc_data" 20 #define CDT_FILE_BASE "cdt_data" 21 #define CDC_FILE_DIR "cdc_data.dir" 22 #define CDC_FILE_PAG "cdc_data.pag" 23 #define CDT_FILE_DIR "cdt_data.dir" 24 #define CDT_FILE_PAG "cdt_data.pag" 25 26 /* Some file scope variables for accessing the database */ 27 static GDBM_FILE cdc_dbm_ptr = NULL; 28 static GDBM_FILE cdt_dbm_ptr = NULL; 29 30 31 /* This function initializes access to the database. If the parameter 32 new_database is true, then a new database is started. 33 */ 34 int database_initialize(const int new_database) 35 { 36 int open_mode = O_CREAT | O_RDWR; 37 38 /* If any existing database is open then close it */ 39 if (cdc_dbm_ptr) gdbm_close(cdc_dbm_ptr); 40 if (cdt_dbm_ptr) gdbm_close(cdt_dbm_ptr); 41 42 if (new_database) { 43 /* delete the old files */ 44 (void) unlink(CDC_FILE_PAG); 45 (void) unlink(CDC_FILE_DIR); 46 (void) unlink(CDT_FILE_PAG); 47 (void) unlink(CDT_FILE_DIR); 48 } 49 /* Open some new files, creating them if required */ 50 cdc_dbm_ptr = gdbm_open(CDC_FILE_BASE, 0, open_mode, 0644, NULL); 51 cdt_dbm_ptr = gdbm_open(CDT_FILE_BASE, 0, open_mode, 0644, NULL); 52 if (!cdc_dbm_ptr || !cdt_dbm_ptr) { 53 fprintf(stderr, "Unable to create database\n"); 54 cdc_dbm_ptr = cdt_dbm_ptr = NULL; 55 return (0); 56 } 57 return (1); 58 59 } /* database_initialize */ 60 61 void database_close(void) 62 { 63 if (cdc_dbm_ptr) gdbm_close(cdc_dbm_ptr); 64 if (cdt_dbm_ptr) gdbm_close(cdt_dbm_ptr); 65 66 cdc_dbm_ptr = cdt_dbm_ptr = NULL; 67 68 } /* database_close */ 69 70 /* 71 This function retrieves a single catalog entry, when passed a pointer 72 pointing to catalog text string. If the entry is not found then the 73 returned data has an empty catalog field. */ 74 CdcEntry get_CdcEntry(const char *cd_catalog_ptr) 75 { 76 CdcEntry entry_to_return; 77 char entry_to_find[CAT_CAT_LEN + 1]; 78 datum local_data_datum; 79 datum local_key_datum; 80 81 memset(&entry_to_return, '\0', sizeof(entry_to_return)); 82 83 /* check database initialized and parameters valid */ 84 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (entry_to_return); 85 if (!cd_catalog_ptr) return (entry_to_return); 86 if (strlen(cd_catalog_ptr) >= CAT_CAT_LEN) return (entry_to_return); 87 88 /* ensure the search key contains only the valid string and nulls */ 89 memset(&entry_to_find, '\0', sizeof(entry_to_find)); 90 strcpy(entry_to_find, cd_catalog_ptr); 91 92 local_key_datum.dptr = (void *) entry_to_find; 93 local_key_datum.dsize = sizeof(entry_to_find); 94 95 memset(&local_data_datum, '\0', sizeof(local_data_datum)); 96 local_data_datum = gdbm_fetch(cdc_dbm_ptr, local_key_datum); 97 if (local_data_datum.dptr) { 98 memcpy(&entry_to_return, (char *)local_data_datum.dptr, local_data_datum.dsize); 99 } 100 return (entry_to_return); 101 } /* get_CdcEntry */ 102 103 104 /* 105 This function retrieves a single track entry, when passed a pointer 106 pointing to a catalog string and a track number. If the entry is not 107 found then the returned data has an empty catalog field. */ 108 CdtEntry get_CdtEntry(const char *cd_catalog_ptr, const int track_no) 109 { 110 CdtEntry entry_to_return; 111 char entry_to_find[CAT_CAT_LEN + 10]; 112 datum local_data_datum; 113 datum local_key_datum; 114 115 memset(&entry_to_return, '\0', sizeof(entry_to_return)); 116 117 /* check database initialized and parameters valid */ 118 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (entry_to_return); 119 if (!cd_catalog_ptr) return (entry_to_return); 120 if (strlen(cd_catalog_ptr) >= CAT_CAT_LEN) return (entry_to_return); 121 122 /* setup the search key, which is a composite key of catalog entry 123 and track number */ 124 memset(&entry_to_find, '\0', sizeof(entry_to_find)); 125 sprintf(entry_to_find, "%s %d", cd_catalog_ptr, track_no); 126 127 local_key_datum.dptr = (void *) entry_to_find; 128 local_key_datum.dsize = sizeof(entry_to_find); 129 130 memset(&local_data_datum, '\0', sizeof(local_data_datum)); 131 local_data_datum = gdbm_fetch(cdt_dbm_ptr, local_key_datum); 132 if (local_data_datum.dptr) { 133 memcpy(&entry_to_return, (char *) local_data_datum.dptr, local_data_datum.dsize); 134 } 135 return (entry_to_return); 136 } /* get_CdtEntry */ 137 138 139 /* This function adds a new catalog entry. */ 140 int add_CdcEntry(const CdcEntry entry_to_add) 141 { 142 char key_to_add[CAT_CAT_LEN + 1]; 143 datum local_data_datum; 144 datum local_key_datum; 145 int result; 146 147 /* check database initialized and parameters valid */ 148 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (0); 149 if (strlen(entry_to_add.catalog) >= CAT_CAT_LEN) return (0); 150 151 /* ensure the search key contains only the valid string and nulls */ 152 memset(&key_to_add, '\0', sizeof(key_to_add)); 153 strcpy(key_to_add, entry_to_add.catalog); 154 155 local_key_datum.dptr = (void *) key_to_add; 156 local_key_datum.dsize = sizeof(key_to_add); 157 local_data_datum.dptr = (void *) &entry_to_add; 158 local_data_datum.dsize = sizeof(entry_to_add); 159 160 result = gdbm_store(cdc_dbm_ptr, local_key_datum, local_data_datum, GDBM_REPLACE); 161 162 /* dbm_store() uses 0 for success */ 163 if (result == 0) return (1); 164 return (0); 165 166 } /* add_CdcEntry */ 167 168 169 /* This function adds a new catalog entry. The access key is the 170 catalog string and track number acting as a composite key */ 171 int add_CdtEntry(const CdtEntry entry_to_add) 172 { 173 char key_to_add[CAT_CAT_LEN + 10]; 174 datum local_data_datum; 175 datum local_key_datum; 176 int result; 177 178 /* check database initialized and parameters valid */ 179 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (0); 180 if (strlen(entry_to_add.catalog) >= CAT_CAT_LEN) return (0); 181 182 /* ensure the search key contains only the valid string and nulls */ 183 memset(&key_to_add, '\0', sizeof(key_to_add)); 184 sprintf(key_to_add, "%s %d", entry_to_add.catalog, entry_to_add.track_no); 185 186 local_key_datum.dptr = (void *) key_to_add; 187 local_key_datum.dsize = sizeof(key_to_add); 188 local_data_datum.dptr = (void *) &entry_to_add; 189 local_data_datum.dsize = sizeof(entry_to_add); 190 191 result = gdbm_store(cdt_dbm_ptr, local_key_datum, local_data_datum, GDBM_REPLACE); 192 193 /* dbm_store() uses 0 for success and -ve numbers for errors */ 194 if (result == 0) 195 return (1); 196 return (0); 197 } /* add_CdtEntry */ 198 199 200 int del_CdcEntry(const char *cd_catalog_ptr) { 201 char key_to_del[CAT_CAT_LEN + 1]; 202 datum local_key_datum; 203 int result; 204 205 /* check database initialized and parameters valid */ 206 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (0); 207 if (strlen(cd_catalog_ptr) >= CAT_CAT_LEN) return (0); 208 209 /* ensure the search key contains only the valid string and nulls */ 210 memset(&key_to_del, '\0', sizeof(key_to_del)); 211 strcpy(key_to_del, cd_catalog_ptr); 212 213 local_key_datum.dptr = (void *) key_to_del; 214 local_key_datum.dsize = sizeof(key_to_del); 215 216 result = gdbm_delete(cdc_dbm_ptr, local_key_datum); 217 218 /* dbm_delete() uses 0 for success */ 219 if (result == 0) return (1); 220 return (0); 221 222 } /* del_CdcEntry */ 223 224 int del_CdtEntry(const char *cd_catalog_ptr, const int track_no) { 225 char key_to_del[CAT_CAT_LEN + 10]; 226 datum local_key_datum; 227 int result; 228 229 /* check database initialized and parameters valid */ 230 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (0); 231 if (strlen(cd_catalog_ptr) >= CAT_CAT_LEN) return (0); 232 233 /* ensure the search key contains only the valid string and nulls */ 234 memset(&key_to_del, '\0', sizeof(key_to_del)); 235 sprintf(key_to_del, "%s %d", cd_catalog_ptr, track_no); 236 237 local_key_datum.dptr = (void *) key_to_del; 238 local_key_datum.dsize = sizeof(key_to_del); 239 240 result = gdbm_delete(cdt_dbm_ptr, local_key_datum); 241 242 /* dbm_delete() uses 0 for success */ 243 if (result == 0) return (1); 244 return (0); 245 246 } /* del_CdtEntry */ 247 248 249 /* This function searches for a catalog entry, where the catalog 250 text contains the provided search text. If the search text points 251 to a null character then all entries are considered to match */ 252 CdcEntry search_CdcEntry(const char *cd_catalog_ptr, int *first_call_ptr) 253 { 254 static int local_first_call = 1; 255 CdcEntry entry_to_return; 256 datum local_data_datum; 257 static datum local_key_datum; /* notice this must be static */ 258 259 memset(&entry_to_return, '\0', sizeof(entry_to_return)); 260 261 /* check database initialized and parameters valid */ 262 if (!cdc_dbm_ptr || !cdt_dbm_ptr) return (entry_to_return); 263 if (!cd_catalog_ptr || !first_call_ptr) return (entry_to_return); 264 if (strlen(cd_catalog_ptr) >= CAT_CAT_LEN) return (entry_to_return); 265 266 /* protect against never passing *first_call_ptr true */ 267 if (local_first_call) { 268 local_first_call = 0; 269 *first_call_ptr = 1; 270 } 271 if (*first_call_ptr) { 272 *first_call_ptr = 0; 273 local_key_datum = gdbm_firstkey(cdc_dbm_ptr); 274 } else { 275 local_key_datum = gdbm_nextkey(cdc_dbm_ptr, local_key_datum); 276 } 277 278 do { 279 if (local_key_datum.dptr != NULL) { 280 /* an entry was found */ 281 local_data_datum = gdbm_fetch(cdc_dbm_ptr, local_key_datum); 282 if (local_data_datum.dptr) { 283 memcpy(&entry_to_return, (char *) local_data_datum.dptr, local_data_datum.dsize); 284 285 /* check if search string occures in the entry */ 286 if (!strstr(entry_to_return.catalog, cd_catalog_ptr)) { 287 memset(&entry_to_return, '\0', sizeof(entry_to_return)); 288 local_key_datum = gdbm_nextkey(cdc_dbm_ptr, local_key_datum); 289 } 290 } 291 } 292 } while (local_key_datum.dptr && 293 local_data_datum.dptr && 294 (entry_to_return.catalog[0] == '\0')); 295 /* Finished finding entries, either there are no more or one matched */ 296 297 return (entry_to_return); 298 } /* search_cdc_entry */
代码:
1 #ifndef cdData_h 2 #define cdData_h 3 4 #include <unistd.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <fcntl.h> 8 #include <string.h> 9 #include <gdbm.h> 10 11 /* The catalog table */ 12 #define CAT_CAT_LEN 30 13 #define CAT_TITLE_LEN 70 14 #define CAT_TYPE_LEN 30 15 #define CAT_ARTIST_LEN 70 16 17 typedef struct { 18 char catalog[CAT_CAT_LEN + 1]; 19 char title[CAT_TITLE_LEN + 1]; 20 char type[CAT_TYPE_LEN + 1]; 21 char artist[CAT_ARTIST_LEN + 1]; 22 }CdcEntry; 23 24 /* The tracks table, one entry per track */ 25 #define TRACK_CAT_LEN CAT_CAT_LEN 26 #define TRACK_TTEXT_LEN 70 27 28 typedef struct { 29 char catalog[TRACK_CAT_LEN + 1]; 30 int track_no; 31 char track_txt[TRACK_TTEXT_LEN + 1]; 32 }CdtEntry; 33 34 /* Menu options */ 35 typedef enum { 36 mo_invalid, 37 mo_add_cat, 38 mo_add_tracks, 39 mo_del_cat, 40 mo_find_cat, 41 mo_list_cat_tracks, 42 mo_del_tracks, 43 mo_count_entries, 44 mo_exit 45 } menu_options; 46 47 /* For convenience we also put the prototype for the functions 48 to access the data here */ 49 50 /* Initialization and termination functions */ 51 int database_initialize(const int new_database); 52 void database_close(void); 53 54 /* two for simple data retrival */ 55 CdcEntry get_CdcEntry(const char *cd_catalog_ptr); 56 CdtEntry get_CdtEntry(const char *cd_catalog_ptr, const int track_no); 57 58 /* two for data addition */ 59 int add_CdcEntry(const CdcEntry entry_to_add); 60 int add_CdtEntry(const CdtEntry entry_to_add); 61 62 /* two for data deletion */ 63 int del_CdcEntry(const char *cd_catalog_ptr); 64 int del_CdtEntry(const char *cd_catalog_ptr, const int track_no); 65 66 /* one search function */ 67 CdcEntry search_CdcEntry(const char *cd_catalog_ptr, int *first_call_ptr); 68 69 /* local prototypes */ 70 int command_mode(int argc, char *argv[]); 71 void announce(void); 72 menu_options show_menu(const CdcEntry *current_cdc); 73 int get_confirm(const char *question); 74 int enter_new_cat_entry(CdcEntry *entry_to_update); 75 void enter_new_track_entries(const CdcEntry *entry_to_add_to); 76 void del_cat_entry(const CdcEntry *entry_to_delete); 77 void del_track_entries(const CdcEntry *entry_to_delete); 78 CdcEntry find_cat(void); 79 void list_tracks(const CdcEntry *entry_to_use); 80 void count_all_entries(void); 81 void display_cdc(const CdcEntry *cdc_to_show); 82 void display_cdt(const CdtEntry *cdt_to_show); 83 void strip_return(char *string_to_strip); 84 85 #endif
测试文件:
//This is c program code! /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= * 文档信息: *** :~/WORKM/stutyCode/linuxPrograming/manageDisk/diskManage.c * 版权声明: *** :(魎魍魅魑)MIT * 联络信箱: *** :guochaoxxl@163.com * 创建时间: *** :2020年12月12日的上午10:43 * 文档用途: *** :数据结构与算法分析-c语言描述 * 作者信息: *** :guochaoxxl(http://cnblogs.com/guochaoxxl) * 修订时间: *** :2020年第49周 12月12日 星期六 上午10:43 (第347天) * 文件描述: *** :自行添加 * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/ /* CD Database Application Beginning Linux Programming Version: Terminals Copyright (c) 1996,2007 Wrox Press This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Fee Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hopes that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Notes This version of the CD database application has been written using the information presented in the Terminals chapter. It is derived from the shell script presented in the Shell Programming chapter. It has not been redesigned for the C implementation, so many features of the shell original can still be seen in this version. There are some problems with this implementation that will be resolved in later revisions: It does not deal with commas in titles. It has a practical limit on tracks per CD to keep them on screen. The program deliberately uses the standard input and output file streams. It does not deal with re-directed input or output explicitly. */ #include "cdData.h" int main(int argc, char *argv[]) { menu_options current_option; CdcEntry current_CdcEntry; int command_result; memset(¤t_CdcEntry, '\0', sizeof(current_CdcEntry)); if (argc > 1) { command_result = command_mode(argc, argv); exit(command_result); } announce(); if (!database_initialize(0)) { fprintf(stderr, "Sorry, unable to initialize database\n"); fprintf(stderr, "To create a new database use %s -i\n", argv[0]); exit(EXIT_FAILURE); } while(current_option != mo_exit) { current_option = show_menu(¤t_CdcEntry); switch(current_option) { case mo_add_cat: if (enter_new_cat_entry(¤t_CdcEntry)) { if (!add_CdcEntry(current_CdcEntry)) { fprintf(stderr, "Failed to add new entry\n"); memset(¤t_CdcEntry, '\0', sizeof(current_CdcEntry)); } } break; case mo_add_tracks: enter_new_track_entries(¤t_CdcEntry); break; case mo_del_cat: del_cat_entry(¤t_CdcEntry); break; break; case mo_find_cat: current_CdcEntry = find_cat(); break; case mo_list_cat_tracks: list_tracks(¤t_CdcEntry); break; case mo_del_tracks: del_track_entries(¤t_CdcEntry); break; case mo_count_entries: count_all_entries(); break; case mo_exit: break; case mo_invalid: break; default: break; } /* switch */ } /* while */ database_close(); return 0; } /* main */
Makefile文件:
1 #all: curses_app 2 #Uncomment and edit the line below if necessary 3 #CFLAGS=-I/usr/include/ncurses 4 #LDFLAGS=-lcurses 5 INCLUDE=/usr/include/gdbm 6 LIBS=-lgdbm 7 CFLAGS= 8 testDiskManage:testDiskManage.c appUi.c cdAccess.c 9 gcc $^ -I$(INCLUDE) -o $@ ${CFLAGS} $(LIBS)
分了模块,加了gdbm数据库的应用
人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。