gpt4 book ai didi

c - 根据插入时的变量对数组进行排序

转载 作者:行者123 更新时间:2023-11-30 19:39:52 25 4
gpt4 key购买 nike

我一直在为图书结构的图书馆数据库编写一个小程序。数组被 malloc 分配并在每个索引 ibsn long 变量中用 0 进行初始化,并提示菜单允许选择。添加书籍后,它将被放置到数组中的第一个可用位置(ISBN 编号为 !=0 的第一个位置)。
我的问题是如何将一本书添加到数组中,从而将其按 isbn 编号排序,首先检查数组中是否有空间?
示例:将 ISBN 1234 的书籍输入数组;第二本书添加了 ISBN 123,并放置在第一个索引处,将前一本书移动到下一个索引。

void addbook(book_t* lib, int size)
{
int i;

//// Loop through the array until you find an empty element
for (i = 0; i < size; i++) {
/// Found an empty element
if ((lib + i)->isbn == 0) {
//// Ask for and store the book details
printf("Please enter the book name\n");
scanf("%s", (lib + i)->name);
printf("Please enter the book author\n");
scanf("%s", (lib + i)->author);
printf("Please enter the book number\n");
scanf("%ld", &(lib + i)->isbn);
printf("Please enter the book price\n");
scanf("%lf", &(lib + i)->price);

printf("We will now ask you for the release date of the book by day then month then year");

printf("\nPlease enter release date for this book (dd):"); //user able to change default
scanf("%d", &(lib + i)->releaseDate.date);

printf("\nPlease enter release month for this book (mm):"); //user able to change default
scanf("%d", &(lib + i)->releaseDate.month);

printf("\nPlease enter release year for this book (yyyy):"); //user able to change default
scanf("%d", &(lib + i)->releaseDate.year);

printf("\nDate entered is (%d / %d / %d)", (lib + i)->releaseDate.date, (lib + i)->releaseDate.month, (lib + i)->releaseDate.year); //user able to change default
/// Set i to size so that the loop finished
i = size;
}

//// If no empty element found and at the last element of the array
/// then library is not found
else if (i == size - 1)
{
printf("The array is full\n");
}
}
}

我在删除一本书时采用了类似的方法,如果找到搜索的书,它将被移动到数组中的最后一个空间,并将其变量设置为 0。

void deleteBook(book_t *lib, int size) {
int i, j, location = 0;
long searchISBN;
int found = 0;

printf("Enter ISBN to search\n");
scanf("%ld", &searchISBN);

for (i = 0; i < size; i++) {

if ((lib + i)->isbn == searchISBN) {
found++;
printf("Book Name %s\n", (lib + i)->name);
printf("Book Author %s\n", (lib + i)->author);
printf("Book ISBN %ld\n", (lib + i)->isbn);
printf("Book Price %lf\n", (lib + i)->price);
location = i;
i = size;
} else
if (i == size - 1) {
location++;

}//add to location and try again
}
if (found == 1) {
for (j = location; j < size; j++) {
strcpy(lib->name, (lib + j)->name);
strcpy(lib->author, (lib + j)->author);
(lib)->isbn = (lib + j)->isbn;
(lib)->price = (lib + j)->price; //user able to change default
(lib)->releaseDate.date = (lib + j)->releaseDate.date;
(lib)->releaseDate.month = (lib + j)->releaseDate.month;
(lib)->releaseDate.year = (lib + j)->releaseDate.year;

}//end swapping of elements

strcpy(lib->name, "0");
strcpy(lib->author, "0");
(lib)->isbn = 0;
(lib)->price = 0;
(lib)->releaseDate.date = 0;
(lib)->releaseDate.month = 0;
(lib)->releaseDate.year = 0;
} else {
printf("not found");
}
}//end deleteBook method

最佳答案

您的函数deleteBook无法正常工作:它将找到的条目之后的所有条目的字段复制到数组中的第一个条目上。您应该使用 memmove() 将剩余条目复制为一个 block 。使用 memmove() 而不是 memcpy(),因为源内存区域和目标内存区域重叠。

这是更正后的版本:

#include <stdio.h>
#include <string.h>

void deleteBook(book_t *lib, int size) {
long searchISBN;
int found = 0;

printf("Enter ISBN to search\n");
if (scanf("%ld", &searchISBN) != 1)
return;

for (int i = 0; i < size;) {
if (lib[i].isbn == searchISBN) {
book_t book = { 0 }; // empty book record
found++;
// display book data before erasing it
printf("Book Name %s\n", lib[i].name);
printf("Book Author %s\n", lib[i].author);
printf("Book ISBN %ld\n", lib[i].isbn);
printf("Book Price %lf\n", lib[i].price);
// copy the remainder elements one position to the left
memmove(lib + i, lib + i + 1, sizeof(*lib) * (size - i - 1))
// reinitialize the last entry
memcpy(lib + size - 1, &book, sizeof(*lib));
// rescan the current entry in case of duplicates
// hence do not increment i
} else {
i++; // test the next entry
}
}
if (found == 0) {
printf("not found");
}
}

您可以使用类似的技术在表中的适当位置插入新条目:

void addbook(book_t *lib, int size) {
book_t book = { 0 }; // empty book record
int i, used;

// Loop through the array and pack empty elements
for (i = used = 0; i < size; i++) {
if (lib[i].isbn != 0) {
if (used < i) {
memcpy(lib + used, lib + i, sizeof(*lib));
}
used++;
}
}
// reset unused elements:
for (i = used; i < size; i++) {
if (lib[i].isbn != 0) {
memcpy(lib + i, &book, sizeof(*lib));
}
}

// check if the array is full:
if (used >= size) {
printf("The array is full\n");
return;
}

// Ask for and store the book details to local book structure
printf("Please enter the book name\n");
if (scanf("%s", book.name) != 1)
return;
printf("Please enter the book author\n");
if (scanf("%s", book.author) != 1)
return;
printf("Please enter the book number\n");
if (scanf("%ld", &book.isbn) != 1)
return;
printf("Please enter the book price\n");
if (scanf("%lf", &book.price) != 1)
return;

printf("We will now ask you for the release date of the book by day then month then year");

printf("\nPlease enter release date for this book (dd):");
if (scanf("%d", &book.releaseDate.date) != 1)
return;

printf("\nPlease enter release month for this book (mm):");
if (scanf("%d", &book.releaseDate.month) != 1)
return;

printf("\nPlease enter release year for this book (yyyy):");
if (scanf("%d", &book.releaseDate.year) != 1)
return;

printf("\nDate entered is (%d / %d / %d)",
book.releaseDate.date, book.releaseDate.month, book.releaseDate.year);

//// Loop through the array until you find location to insert book
for (i = 0; i < used; i++) {
if (lib[i].isbn > book.isbn)
break;
}
// book should be inserted at position i

// shift book with larger ISBNs
memmove(lib + i + 1, lib + i, sizeof(*lib) * (used - i));
used++;
// copy book into the array
memcpy(lib + i, &book, sizeof(*lib));
}

对于生产代码,您需要适本地处理 scanf 错误。

这些插入和删除方法效率不高,因为平均每次操作都会复制一半的数据库。更有效的实现将使用链接列表来避免复制数据,并使处理数量可变的书籍变得更容易。

关于c - 根据插入时的变量对数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36015531/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com