Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π² LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 83

Автор НСйл ΠœΡΡ‚ΡŒΡŽ

 (void)fgets(tmp_str, TMP_STRING_LEN, stdin);

 strip_return(tmp_str);

 strncpy(new_entry.type, tmp_str, CAT_TYPE_LEN - 1);

 printf("Enter artist: ");

 (void)fgets(tmp_str, TMP_STRING_LEN, stdin);

 strip_return(tmp_str);

 strncpy(new_entry.artist, tmp_str, CAT_ARTIST_LEN - 1);

 printf("\nNew catalog entry entry is :-\n");

 display_cdc(&new_entry);

 if (get_confirm("Add this entry ? ")) {

  memcpy(entry_to_update, &new_entry, sizeof(new_entry));

  return(1);

 }

 return(0);

}

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π΅ примСняСтС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ gets, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅Ρ‚ способа ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π±ΡƒΡ„Π΅Ρ€Π°. ВсСгда ΠΈΠ·Π±Π΅Π³Π°ΠΉΡ‚Π΅ примСнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ gets! 

10. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ enter_new_track_entries для Π²Π²ΠΎΠ΄Π° ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π΄ΠΎΡ€ΠΎΠΆΠΊΠ΅. Π­Ρ‚Π° функция Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ слоТнСС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Π²ΠΎΠ΄Π° элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚Π΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ элСмСнту-Π΄ΠΎΡ€ΠΎΠΆΠΊΠ΅ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌ:

static void enter_new_track_entries(const cdc_entry *entry_to_add_to) {

 cdt_entry new_track, existing_track;

 char tmp_str[TMP_STRING_LEN + 1];

 int track_no = 1;

 if (entry_to_add_to->catalog[0] == '\0') return;

 printf("\nUpdating tracks for %s\n", entry_to_add_to->catalog);

 printf("Press return to leave existing description unchanged, \n");

 printf(" a single d to delete this and remaining tracks, \n");

 printf(" or new track description\n");

 while(1) {

11. Π‘Π½Π°Ρ‡Π°Π»Π° Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, сущСствуСт Π»ΠΈ ΡƒΠΆΠ΅ Π΄ΠΎΡ€ΠΎΠΆΠΊΠ° с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ. Π’ зависимости ΠΎΡ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ мСняСтся строка ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΡ:

  memset(&new_track, '\0', sizeof(new_track));

  existing_track = get_cdt_entry(entry_to_add_to->catalog,

   track_no);

  if (existing_track.catalog[0]) {

   printf("\tTrack %d: %s\n", track_no,

    existing_track.track_txt);

   printf("\tNew text: ");

  } else {

   printf("\tTrack %d description: ", track_no);

  }

  fgets(tmp_str, TMP_STRING_LEN, stdin);

  strip_return(tmp_str);

12. Π•сли для Π΄Π°Π½Π½ΠΎΠΉ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ Π½Π΅ сущСствуСт элСмСнт ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΅Π³ΠΎ Π½Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ», ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ большС Π½Π΅Ρ‚ Π΄ΠΎΡ€ΠΎΠΆΠ΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Π΄ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ:

  if (strlen(tmp_str) == 0) {

   if (existing_track.catalog[0] == '\0') {

    /* НСт Π² Π½Π°Π»ΠΈΡ‡ΠΈΠΈ элСмСнта, поэтому вставка Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ */

    break;

   } else {

    /* ΠžΡΡ‚Π°Π²Π»ΡΠ΅ΠΌ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт,

       ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π°ΠΌ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π΄ΠΎΡ€ΠΎΠΆΠΊΠ΅ */

    track_no++;

    continue;

   }

  }

13. Π•сли ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²Π²Π΅Π΄Π΅Ρ‚ Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½Ρ‹ΠΉ символ d, это ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΡŽ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ ΠΈ Π΄ΠΎΡ€ΠΎΠΆΠ΅ΠΊ с большими Π½ΠΎΠΌΠ΅Ρ€Π°ΠΌΠΈ. Ѐункция del_cdt_entry Π²Π΅Ρ€Π½Π΅Ρ‚ false, Ссли Π½Π΅ смоТСт Π½Π°ΠΉΡ‚ΠΈ Π΄ΠΎΡ€ΠΎΠΆΠΊΡƒ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ слСдуСт ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ:

  if ((strlen(tmp_str) == 1) && tmp_str[0] == 'd') { /* УдаляСт эту ΠΈ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ */

   while (del_cdt_entry(entry_to_add_to->catalog, track_no)) {

    track_no++;

   }

   break;

  }

14. Π’ этом ΠΏΡƒΠ½ΠΊΡ‚Π΅ приводится ΠΊΠΎΠ΄ для вставки Π½ΠΎΠ²ΠΎΠΉ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ ΠΈΠ»ΠΈ обновлСния ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ. Π’Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚Π΅ элСмСнт cdt_entry структуры new_track ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… add_cdt_entry для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π² Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…:

  strncpy(new_track. track_txt, tmp_str, TRACK_TTEXT_LEN - 1);

  strcpy(new_track.catalog, entry_to_add_to->catalog);

  new_track.track_no = track_no;

  if (!add_cdt_entry(new_track)) {

   fprintf(stderr, "Failed to add new track\n");

   break;

  }

  track_no++;

 } /* while */

}

15. Π€ΡƒΠ½ΠΊΡ†ΠΈΡ del_cat_entry удаляСт элСмСнт ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°. Никогда Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΠΉΡ‚Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ для Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°.

static void del_cat_entry(const cdc_entry *entry_to_delete) {

 int track_no = 1;

 int delete_ok;

 display_cdc(entry_to_delete);

 if (get_confirm("Delete this entry and all it's tracks? ")) {

  do {

   delete_ok = del_cdt_entry(entry_to_delete->catalog, track_no);

   track_no++;

  } while(delete_ok);

  if (!del_cdc_entry(entry_to_delete->catalog)) {

   fprintf(stderr, "Failed to delete entry\n");

  }

 }

}

16. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ функция β€” ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° для удалСния всСх Π΄ΠΎΡ€ΠΎΠΆΠ΅ΠΊ элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°:

static void del_track_entries(const cdc_entry *entry_to_delete) {

 int track_no = 1;

 int delete_ok;

 display_cdc(entry_to_delete);

 if (get_confirm("Delete tracks for this entry? ")) {

  do {

   delete_ok = del_cdt_entry(entry_to_delete->catalog, track_no);

   track_no++;

  } while(delete_ok);

 }

}

17. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΎΡ‡Π΅Π½ΡŒ простоС срСдство поиска, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ввСсти строку ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΠΏΠΎΠΈΡ‰ΠΈΡ‚Π΅ элСмСнты ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°, содСрТащиС строку. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ нСсколько элСмСнтов с Ρ‚Π°ΠΊΠΎΠΉ строкой, просто ΠΏΠΎ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽΡ‚ΡΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ всС Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹Π΅:

static cdc_entry find_cat(void) {

 cdc_entry item_found;

 char tmp_str[TMP_STRING_LEN + 1];

 int first_call = 1;

 int any_entry_found = 0;

 int string ok;

 int entry_selected = 0;

 do {

  string_ok = 1;

  printf("Enter string to search for in catalog entry: ");

  fgets(tmp_str, TMP_STRING_LEN, stdin);

  strip_return(tmp_str);

  if (strlen(tmp_str) > CAT_CAT_LEN) {

   fprintf(stderr, "Sorry, string too long, maximum %d \

    characters\n", CAT_CAT_LEN);

   string_ok = 0;

  }

 } while (!string_ok);

 while (!entry_selected) {

  item_found = search_cdc_entry(tmp_str, &firstcall);

  if (item_found.catalog[0] != '\0') {

   any_entry_found = 1;

   printf("\n");

   display_cdc(&item_found);

   if (get_confirm("This entry? ")) {

    entry_selected = 1;

   }

  } else {

   if (any_entry_found) printf("Sorry, no more matches found\n");

   else printf("Sorry, nothing found\n");

   break;

  }

 }

 return(item_found);

}

18. Π€ΡƒΠ½ΠΊΡ†ΠΈΡ list_tracks β€” ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π°, которая Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ всС Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ для Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°:

static void list_tracks(const cdc_entry *entry_to_use) {

 int track_no = 1;

 cdt_entry entry_found;

 display_cdc(entry_to_use);

 printf("\nTracks\n");

 do {

  entry_found = get_cdt_entry(entry_to_use->catalog, track_no);

  if (entry_found.catalog[0]) {

   display_cdt(&entry_found);

   track_no++;

  }

 } while(entry_found.catalog[0]);

 (void)get_confirm("Press return");

} /* list_tracks */

19. Π€ΡƒΠ½ΠΊΡ†ΠΈΡ count_all_entries подсчитываСт всС Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ:

static void count_all_entries(void) {

 int cd_entries_found = 0;

 int track_entries_found = 0;

 cdc_entry cdc_found;

 cdt_entry cdt_found;

 int track_no = 1;

 int first_time = 1;

 char *search_string = "";

 do {

  cdc_found = search_cdc_entry(search_string, &first_time);

  if (cdc_found.catalog[0]) {

   cd_entries_found++;

   track_no = 1;

   do {

    cdt_found = get_cdt_entry(cdc_found.catalog, track_no);

    if (cdt_found.catalog[0]) {

     track_entries_found++;

     track_no++;

    }

   } while (cdt_found.catalog[0]);

  }

 } while (cdc_found.catalog[0]);

 printf("Found %d CDs, with a total of %d tracks\n",

  cd_entries_found, track_entries_found);

 (void)get_confirm("Press return");

}

20. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ вас Π΅ΡΡ‚ΡŒ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° display_cdc для Π²Ρ‹Π²ΠΎΠ΄Π° элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°:

static void display_cdc(const cdc_entry *cdc_to_show) {

 printf("Catalog: %s\n", cdc_to_show->catalog);

 printf("\ttitle: %s\n", cdc_to_show->title);

 printf("\ttype: %s\n", cdc_to_show->type);

 printf("\tartist: %s\n", cdc_to_show->artist);

}

ΠΈ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° display_cdt для отобраТСния элСмСнта-Π΄ΠΎΡ€ΠΎΠΆΠΊΠΈ:

static void display_cdt(const cdt_entry *cdt_to_show) {

 printf("%d: %s\n", cdt_to_show->track_no,

  cdt_to_show->track_txt);

}

21. Π‘луТСбная функция strip_return удаляСт Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ строку символ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки. ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Linux, ΠΊΠ°ΠΊ ΠΈ UNIX, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠ΄ΠΈΠ½ символ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° строки для обозначСния ΠΊΠΎΠ½Ρ†Π° строки.

static void strip_return(char *string_to_strip) {

 int len;

 len = strlen(string_to_strip);

 if (string_to_strip[len - 1] == '\n')

 string_to_strip[len - 1] = '\0';

}

22. Π€ΡƒΠ½ΠΊΡ†ΠΈΡ command_mode ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для синтаксичСского Π°Π½Π°Π»ΠΈΠ·Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки. Ѐункция getopt β€” Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ способ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ стандартным соглашСниям, принятым Π² систСмС Linux.

static int command_mode(int argc, char *argv[]) {

 int c;

 int result = EXIT_SUCCESS;

 char *prog_name = argv[0];

 /* Π­Ρ‚ΠΈ внСшниС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ getopt */

 extern char *optarg;

 extern optind, opterr, optopt;

 while ((c = getopt(argc, argv, ":i")) != -1) {

  switch(c) {

  case 'i':

   if (!database_initialize(1)) {

    result = EXIT_FAILURE;

    fprintf(stderr, "Failed to initialize database\n");

   }

   break;

  case ':':

  case '?':

  default: