在插入时根据变量对数组进行排序

时间:2016-03-15 15:28:04

标签: c arrays

我一直在为书籍结构的图书馆数据库编写一个小程序。数组是malloc分配并在每个索引ibsn long变量中用0&s初始化,并且提示菜单允许选择。添加书籍后,它将被放置在数组中的第一个可用位置(ISBN number is !=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

1 个答案:

答案 0 :(得分:0)

您的函数deleteBook无法正常工作:它会在找到的条目之后复制数组中第一个条目之后的所有条目的字段。您应该将剩余的条目复制为memmove()的块。使用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错误。

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