排序没有被执行

时间:2010-07-10 07:08:33

标签: c

这个程序是一个通过软件工作的书库。问题是,当我按价格对书籍进行分类并打印出来时,它们永远不会被分类!

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
static int count;
struct book
{
    int bookid;
    char name[30];
    char author[30];
    float price;
};
struct book b[40];
void add(void);
void del(void);
void sort(void);
void price(void);
void print(void);
void main(void)
{
    char choice;
    while(1)
    {
        clrscr();
        printf("Enter a choice:\n 1.Add a book.\n 2.Delete a book.\n 3.Sort books by price.\n 4.To print all books details.\n 5.To print the names of the books whose price is less than 1000.\n 6.Exit\n");
        choice=getche();//doing by getch() as getche makes the program rough as it is printed
        switch(choice)
        {
            case'1':add();break;
            case'2':del();break;
            case'3':sort();break;
            case'4':print();break;
            case'5':price();break;
            case'6':exit(0);
            default:printf("Enter a valid choice.");break;
        }
    }/*switch ends*/
}
void add(void)
{
    int i;
    char ch[30];
    clrscr();
    for(i=count;i<40;i++)
    {
    printf("Enter books name:\n");
    gets(b[i].name);
    printf("Enter author's name\n");
    gets(b[i].author);
    printf("Enter price:\n");
    gets(ch);
    b[i].price=atoi(ch);
    b[i].bookid=count;
    break;
    } /* for ends*/
count++;
printf("Dear User,the book has succesfully been added.The book id is %d",b[i].bookid);


getch();
}
void print(void)
{
    int i;
    clrscr();
    for(i=0;i<count;i++)
    {
        printf("Bookid=%d,Name=%s,Author=%s,Price=%f\n",b[i].bookid,b[i].name,b[i].author,b[i].price);

    }
getch();
}

void del(void)
{
    int i,j;
    char ch[10];
    clrscr();
    printf("Enter book id:");
    gets(ch); // how do i put it into the structure as i dont know that which structure it belongs to
    for(i=0;i<count;i++)  //searching
    {
    if(b[i].bookid==atoi(ch))
        {
            for(j=i;j<count;j++)
            {

                b[j]=b[j+1];
            }//for j ends
        }  //if ends
    } /* for of i ends */
    count--;
    //  sort();
getch();
}
//void del(void)
//{

    //  int i;
    //  char ch[10];
     // clrscr();
    //printf("Enter book id:");
       //   gets(ch);
      //    for(i=0;i<40;i++)
      //    {
     //     b[i]=b[i+1];
    //
   //   }
    //  count--;
  //    printf("Dear user,delete succesful");
//getch();
//}
void sort(void)
{
    int in,out;
    struct book temp;
    for(out=0;out<count-1;out++)
    {
        for(in=out+1;out<count;out++)
        {
            if(b[out].price>b[in].price)
            {
                temp=b[out]
                b[out]=b[in];
                b[out]=temp;
            }
        }/*for out ends*/
    }//for in ends
    printf("Dear user,the books are sorted by price.\n");

getch();
}

void price(void)
{
    int i;
    clrscr();
    for(i=0;i<count;i++)
    {
        if(b[i].price<1000)
        {
        printf("%d.%s\n",i+1,b[i].name);
        }
    }
getch();

5 个答案:

答案 0 :(得分:4)

void sort(void)
{
    int in,out;
    struct book temp;
    for(out=0;out<count-1;out++)
    {
        //**(in=out+1;out<count;out++)**//look here please
        for(in=out+1;in<count;in++)
        {
            if(b[out].price>b[in].price)
            {
                temp=b[out]
                b[out]=b[in];
                b[in]=temp;//**b[out]=temp;**//look here plz
            }
        }/*for out ends*/
    }//for in ends
    printf("Dear user,the books are sorted by price.\n");

getch();
}

答案 1 :(得分:1)

除了错误之外的重大错误是不使用C库的qsort函数。除非您打算写一个非常好的排序(可能是快速排序,合并排序或堆排序,具体取决于您的具体需求),qsort会更好,并且需要更少的代码行。

答案 2 :(得分:0)

temp=b[out]
b[out]=b[in];
b[out]=temp;

应该是:

temp=b[out];
b[out] = b[in];
b[in] = temp;

答案 3 :(得分:0)

看起来像是

for(in=out+1;out<count;out++)

应该是

for(in=out+1;out<count;in++)

答案 4 :(得分:0)

这是一个经过测试的修正(我已经这样做了,所以你有一个概述,我认为,好的代码,而不是简化你的作业:你应该理解它而不是复制/粘贴它)。 对于您的问题,sort()函数是最重要的。

#include <stdio.h>

/** Types *************************************************************/

//You should introduce constants, to allow quick changes
#define BOOK_NAME_LEN 30
#define NAME_LEN 30
#define PRICE_NUMBERS 4

#define LIBRARY_CAPACITY 100

//Allows to calculate ID numbers from library capacity (they're linked)
#define STRINGIZE(a) #a
#define STRINGIZE_CONSTANT(a) STRINGIZE(a)
#define ID_NUMBERS (sizeof(STRINGIZE_CONSTANT(\
                    LIBRARY_CAPACITY))/sizeof(char)-1)

typedef struct book Book;
struct book
{
    //id is unsigned
    size_t id;
    char name[BOOK_NAME_LEN+1];
    char author[NAME_LEN+1];
    float price;
};

typedef struct library Library;
struct library {
    Book books[LIBRARY_CAPACITY];
    size_t inventory; //Book count
    size_t id_cnt; //ID counter, never decremented
};

/** Input *************************************************************/

#include <string.h>
#include <stdlib.h>

//Purge stdin after removing ending \n
void clean(const char *buffer, FILE *fp)
{
    char *p = strchr(buffer,'\n');
    if (p != NULL) {
        *p = 0;
    }
    else {
        int c;
        while ((c = fgetc(fp)) != '\n' && c != EOF);
    }
}

//Gets a string from input without ending \n and
//with stdin purge
void get_str(char *str, size_t len) {
    fgets(str, len+1, stdin);
    clean(str, stdin);
}

//Explicit
int get_int_num(size_t n_digits) {
    int ret = 0;

    //Converts an entered string to integer
    char *num = malloc((n_digits+1)*sizeof(char));
    if(num !=NULL) {
        get_str(num, n_digits);
        ret = atoi(num);
        free(num), num = NULL;
    }

    return ret;
}

//Explicit
float get_float_num(size_t n_digits) {
    float ret = 0.f;

    //The comma is a char
    char *num = malloc((n_digits+2)*sizeof(char));
    if(num !=NULL) {
        get_str(num, n_digits+1);
        ret = atof(num);
        free(num), num = NULL;
    }

    return ret;
}

#include <math.h>

//Gets an integer choice in a range, useful for menus
int get_choice(int min, int max) {
    int ret = 0;
    do {
        //The number of digits is deduced from
        //max's one.
        ret = get_int_num(log10(max)+1);
    }while(ret < min || ret > max);

    return ret;
}

/** Library functions **************************************************/

//Printing
void print_library(Library const * const library) {
    for(size_t i = 0 ; i < library->inventory ; ++i) {
        printf("%u) %s BY %s : %.2f USD\n", i+1, library->books[i].name,
                                             library->books[i].author,
                                             library->books[i].price);
    }
}

/* Adding */
void add(Library * const library) {
    //Fills infos
    printf("Name ? ");
    get_str(library->books[library->inventory].name, BOOK_NAME_LEN);
    printf("Author ? ");
    get_str(library->books[library->inventory].author, NAME_LEN);
    printf("Price (%u significative numbers) ? ", PRICE_NUMBERS);
    library->books[library->inventory].price = get_float_num(PRICE_NUMBERS);

    //Unique id from internal library counter
    library->books[library->inventory].id = ++library->id_cnt;
    //And finally increments books count
    library->inventory++;
}
/* End adding */

/* Deleting */

#include <stdbool.h>

//You will be able to remove by anything providing that you
//search the corresponding ID (then, same menu as for sorting)
bool remove_by_id(Library * const library, size_t id) {
    bool ret = false;

    for(size_t i = 0 ; i < library->inventory ; ++i) {
        if(library->books[i].id == id) {
            for(size_t j = i ; j < library->inventory-1 ; ++j) {
                library->books[j] = library->books[j+1];
            }
            library->inventory--;

            ret = true;
        }
    }

    return ret;
}

void del(Library * const library) {
    printf("ID ? ");
    size_t id = get_int_num(ID_NUMBERS);

    printf("Book %u %s.", id, remove_by_id(library, id) ?
                                        "successfully deleted" :
                             "NOT deleted (probably wrong id)");
}
/* End deleting */

/* Sorting */
int cmp_by_price(void const *b1, void const *b2) {
    return ((Book*)b1)->price >= ((Book*)b2)->price;
}

int cmp_by_author(void const *b1, void const *b2) {
    return strcmp(((Book*)b1)->author, ((Book*)b2)->author);
}

int cmp_by_name(void const *b1, void const*b2) {
    return strcmp(((Book*)b1)->name, ((Book*)b2)->name);
}

void sort(Library * const library) {
    printf("Sort by :\n");
    printf("1) Book name\n");
    printf("2) Author name\n");
    printf("3) Price\n");
    printf("Your choice : ");

    //Function pointer to use appropriate comparison function
    int (*compare)(void const *, void const*) = NULL;
    int choice = get_choice(1, 3);
    switch(choice) {
        case 3:
            compare = cmp_by_price;
            break;
        case 2:
            compare = cmp_by_author;
            break;
        case 1:
            compare = cmp_by_name;
            break;
        default:
            break;
    }

    qsort(library->books, library->inventory, sizeof(Book), compare);

    printf("Sorted :\n");
    print_library(library);
}
/* End sorting */

/** Main program ******************************************************/

#include <ctype.h>

bool stop() {
    char c[1] = "";
    printf("\nContinue (\'y\' for yes) ? ");
    get_str(c, 1);

    return tolower(c[0]) != 'y';
}

int main(void) {
    //NEVER use global variables... Prefer to pass them through arguments
    //(of course with pointers otherwise they won't be modified)
    Library library = {{{0}}, 0, 0};

    do {
        printf("Actions available : \n");
        printf("1) Add book\n");
        printf("2) Delete book\n");
        printf("3) Sort books\n");
        printf("Your choice : ");

        int choice = get_choice(1, 3);
        switch(choice) {
            case 1:
                add(&library);
                break;
            case 2:
                del(&library);
                break;
            case 3:
                sort(&library);
                break;
            default:
                break;
        }
    }while(!stop());

    return 0;
}

如果您不理解某些内容,我们会在这里帮助您学习C.