tags:

views:

107

answers:

5

this program is a book library that works via software.the problem is that when i sort the books by price and print them,they never get sorted!

#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();
A: 
temp=b[out]
b[out]=b[in];
b[out]=temp;

Should probably be:

temp=b[out];
b[out] = b[in];
b[in] = temp;
Jonathan Sternberg
This is only error 2, of at least 2. See Sadat's answer.
Brock Adams
A: 

It looks like

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

should be

for(in=out+1;out<count;in++)
Artelius
This is only error 1, of at least 2. See Sadat's answer.
Brock Adams
@Brock: You don't say.
Artelius
+4  A: 
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();
}
Sadat
+1  A: 

The big mistake aside from the errors is not using the C library's qsort function. Unless you're going to write a very good sort (probably quicksort, merge sort, or heap sort depending on your specific needs), qsort will be better and it takes fewer lines of code.

R..
it's homework, likely he must implement his own sort func. The biggest error is to make it without arguments and sorting on global...! gh
ShinTakezou
A: 

Here is a tested correction (I've done this so you have an overview of a, I think, good code, and not to ease your homework : you should understand it and not copy/paste it). For your problem, the sort() function is the most important.

#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;
}

Comment if you don't understand something, we're here to help you learn C after all.

Mister Mystère
what is foo and bool :S
fahad