2010-07-10 108 views
1

此程序是一個通過軟件工作的圖書庫。問題是,當我按價格對書籍進行排序並打印它們時,它們從未得到排序!排序未執行

#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(); 
+0

哈,這是一個冒泡的排序。而且寫得不好。 – Borealid 2010-07-10 07:12:58

+0

不,這是一個選擇排序。 – Artelius 2010-07-10 07:13:48

+0

@Artelius:你是對的。我只是看着循環標題,看到它們是錯誤的,並且假定什麼意思是0-> count和b [in]比b [in + 1]。 – Borealid 2010-07-10 07:17:23

回答

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

大概應該是:

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

這只是錯誤2,至少是2.看到薩達特的答案。 – 2010-07-10 07:20:22

0

它看起來像

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

應該

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

這只是錯誤1,至少是2.看到薩達特的答案。 – 2010-07-10 07:20:47

+0

@布洛克:你不會說。 – Artelius 2010-07-10 14:51:42

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

除了錯誤之外,最大的錯誤是不使用C庫的qsort函數。除非你會寫出一個很好的排序(可能是快速排序,合併排序或堆排序,具體取決於你的具體需求),qsort會更好,它需要更少的代碼行。

+0

這是作業,可能他必須執行他自己的排序功能。最大的錯誤就是讓它無需論證和全球排序...! gh – ShinTakezou 2010-07-10 12:28:10

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語言。

+0

什麼是foo和bool:S – 2010-09-10 19:52:16