Manik Sharma Manik Sharma - 3 months ago 12
C Question

Passing structures to functions in C

Define a struct named: Book. Each book should have a name with exactly 3 letters (abbreviation). Each book should also have a page count (integer), and a price (integer).

Write a program which reads an integer n first, then reads the names, page counts and prices of n books.

Write a function which takes an array of books, and sorts them according to their prices.

Using that function, your program should print the names and page counts of each book with the order of their prices.

*Can someone explain to me how to pass a structure into a function and get this code to work? Or how they would go tackle this question.

struct Book{
char name[3];
int pagec;
int price;
};


void price(int size, struct Book books[size]){
int i,j, tmp;
for(i=0; i<size; i++){
for(j=0; j<size-1; j++){
if(books[j].price < books[j+1].price){
books[j].price = tmp;
books[j].price = books.price[j+1];
books.price[j+1] = tmp;
}
}
}
}

int main(void) {
int n;
scanf("%d", &n);
struct Book books[n];
int i,j;
for(i=0; i<n; i++){
for(j=0; i<1; j++){
scanf("%c", &books[i].name);
scanf("%d", &books[i].pagec);
scanf("%d", &books[i].price);
}
}

price(n, books[n]);
for(i=0; i<n; i++){
printf("%c: %d - %d",books[i].name, books[i].pagec, books[i].price);
}

Answer

The part of your question about how to pass a struct seems to have been well answered, let me get on the second part: how I would tackle that question.

What the struct should be is described well, so we can write without much thinking:

/*
    Define a struct named: Book.
    Each book should have a name with exactly 3 letters (abbreviation).
    Each book should also have a page count (integer), 
    and a price (integer). 
*/
typedef struct book {
  // three characters plus '\0'
  char name[4];
  int pagec;
  int price;
} book_t;

(No need for a typedef you can leave that part out and use the struct directly with struct books)

They want three functions, one is main() we can use it as one of the three. I think getting the info, allocating the memory etc. is a good use of the main() function here.

/*
    Write a program which 

        reads an integer n first, 
        then reads the names, 
        page counts 
        and prices of n books.
*/
int main()
{
  int n, i;
  book_t **books;

  puts("How many books?");
  scanf("%d", &n);

  // we need enough memory to safe "n" structs
  // at first allocate memory for n pointers
  books = malloc(n * sizeof(book_t *));
  // at each pointer allocate enough memory for one struct books
  for (i = 0; i < n; i++) {
    books[i] = malloc(sizeof(book_t));
  }
  // red the info from stdin
  for (i = 0; i < n; i++) {
    printf("Name of book (3 letter abbrev.):");
    scanf("%3s", books[i]->name);
    printf("Number of pages:");
    scanf("%d", &books[i]->pagec);
    printf("Price of book (incl. taxes):");
    scanf("%d", &books[i]->price);
  }
  // call function to sort them
  sort_books(books, n);
  // call a function to print the sorted list
  print_books(books, n);
  // we don't need the memory anymore, so free it
  // at first free the individual structs
  for (i = 0; i < n; i++) {
    free(books[i]);
  }
  // then free the memory holding all of the pointers
  free(books);

  exit(EXIT_SUCCESS);
}

The two functions for printing and sorting are similar in argument handling

/*
    Write a function which takes an array of books,
    and sorts them according to their prices.

   Doesn't say something about output, so sort in situ
*/
void sort_books(book_t ** books, int length)
{
  // OP had bubble sort, so lets do a bubble sort. Why not?
  int i, j;
  book_t *tmp;
  for (i = 0; i < length - 1; i++) {
    for (j = 0; j < length -i - 1; j++) {
      if (books[j]->price < books[j + 1]->price) {
        tmp = books[j];
        books[j] = books[j + 1];
        books[j + 1] = tmp;
      }
    }
  }
}

Printing them all is quite straightforward

/*
   Using that function, your program should 
       print the names and page counts of each book with the order of their prices. 
*/
void print_books(book_t ** books, int length)
{
  int i;
  for (i = 0; i < length; i++) {
    printf("Name %s, pages %d, price %d\n",
       books[i]->name, books[i]->pagec, books[i]->price);
  }
}

It doesn't say anything about the exact order, I took the liberty to use a descending order (from highest to lowest). If you want an ascending order (from lowest to highest) change the comparing in the sorting algorithm:

void sort_books(book_t ** books, int length)
{
  // OP had bubble sort, so lets do a bubble sort
  int i, j;
  book_t *tmp;
  for (i = 0; i < length - 1; i++) {
    for (j = 0; j < length - i - 1; j++) {
      // if (books[j]->price < books[j + 1]->price) {
      if (books[j]->price > books[j + 1]->price) {
         tmp = books[j];
         books[j] = books[j + 1];
         books[j + 1] = tmp;
      }
    }
  }
}

Please be aware that I omitted all checks! You need to check the returns of malloc() and scanf(), if n is an integer, if all of the other numbers are numbers and so on!