Library Management using structure | Sololearn: Learn to code for FREE!

+1

Library Management using structure

https://code.sololearn.com/ca9a14a22A17 This is the longest code that I have done by myself with the help of the internet so far ...the code runs but there are lots of problems including that when I want to add books ,I can't give the name of the author for the first and the last book.Then I wasn't able to do the book issuing properly..So I am badly in need of the help of the expert for finishing it properly.

5/6/2021 6:34:58 PM

Ramisa Fariha

15 Answers

New Answer

+4

A valiant effort indeed Ramisa. Problem 1. You are not initializing your global counting variable to 0. int counting = 0; Problem 2. Your add book function is having problems. We need to use cin.getline() to read the book title and author as they can contain multiple words. The problem is after entering the acc number cin leaves the newline character in the input buffer. Consequently, if we call getline to read the book title it sees the newline and reads it as a zero length string. The solution is to call cin >> ws before cin.getline(). This will discard any outstanding whitespace (such as the newline char) left over from the previous entry. There are also indexing issues with the way you are running your loop. The new addbook() function should now look like this void addbook(struct book b[]) //for adding books { int n; cout << "\nEnter the number of books to add: "; cin >> n; for (int i = 0; i < n; i++) { cout << "\nEnter the information of the book no: " << i + 1 << endl; cout << "\nAccession number: "; cin >> b[counting + i].an; cout << "\nName of the book: "; cin >> ws; // discard remaining whitespace cin.getline(b[counting + i].title, 30); cout << "\nName of the Author: "; cin.getline(b[counting + i].author, 30); b[counting + i].issued = 0; // <- Edit, I forgot this. } counting += n; } Note that there is actually no need to pass the array to the function because it is global. We will leave it as is for now and address this later. Problem 3. No break statement after the issue_a_book switch case. I will look into some other ways of improving your code tomorrow. In general it is very good work though. I am impressed to see how far you have come. The structure of your code is outstanding. EDIT: Forgot to initialise the book.issued variable to 0.

+4

Now we will address the bugs in the find author and find title functions. Both of these problems are caused by the same whitespace issue that we had with the add book function. This time it is because the newline character is left over from the menu option selection. The solution is exactly the same; we add a cin >> ws statement before the getline statement. cout<<"\nEnter the name of the Author: "; cin >> ws; cin.getline(name,20); and cout<<"\nEnter the name of the book: "; cin >> ws; cin.getline(t,30); It's as simple as that.

+4

A little more refactoring. Now that the code is working we can do a little more refactoring. Since the book array is global we don't actually need to pass it to the functions that use it. While some people regard global variables as a No-No they do have uses. In a program such as this where the array is central to the program it can make sense. So we have two options: 1. Remove the array argument from all of the function prototypes and definitions that do not need it and leave the array global. 2. Move the array into main and leave everything else as is. Since this is the cleaner option we shall do that. All that is necessary is to move the array definition into main. Job done. The choice is yours. Either way the function count() does not require any parameters as it simply prints the global variable counting. This could have been inlined with case statement but using a function is cleaner and allows easy modification if required at a later date. Incidentally this is when I realised that I had forgotten to initialise the issued field in the structure during the add function. I kept getting random books out on loan. This is because a global array is initialised to zeros on startup but a local array in main is not. Hence random data was appearing in the data structure. We could do the same for the global variable counting but that would involve changing every function that uses it so we will leave that as is. A final tidy up of the code is now an option. I prefer a top-down coding style. This means main is the first function definition. This involves placing function prototypes before main and moving all other functions below main. I find that this provides a better high level view of the code. To create a function prototype we simply copy the first line of the function definition and place a semicolon at the end. For example... // Declare Functions void title(struct book b[]); void addbook(struct book b[]); void count(); Again, the choice is yours.

+4

By the way Ramisa, this sort of edit, test, debug, repeat loop is completely normal in software development. As is the constant refinement and refactoring of the code. First make it work, then make it work well. Unfortunately, the refactoring and documenting of code stages often get omitted once the software is working. The code gets shipped and everyone forgets about it, until some poor soul has to upgrade the software or fix a bug that has appeared after release. In extreme cases even the make it work well stage gets omitted. Your initial design and factoring of the code was very good. It made it easy to locate any problems and fix them. Many beginners write huge monolithic blocks of code with everything in one sprawling main function. The so called "God function", because it does everything. This makes debugging very difficult. The more time you spend thinking about the problem and breaking it down into individual steps that can be written as simple functions the less problems you are going to have. It also means any problems that you do have are easier to isolate and fix. I can't stress enough how impressed I am with how far you have come in such a short time. Well done.

+4

Thank you so much @ Martin..I'll try my best to do exactly what you've said...I would have given up a long time ago if there was no one to address all the problems that I had faced in doing codes. Words will fail to express my gratitude towards you. I will never forget your assistance throughout my entire life. Thanks for teaching me a lot of things and making it easy as well. It's a regret that I can't meet you in person but I really pray for your well-being.

+2

@Calvin I have done my code following a code on the internet which was written on C..Actually, I have followed like 3 codes to understand and all of them were in C language..It's hard to understand some terms of C and comparing it with C++ if you don't have that much knowledge in C like me. Right now I am doing a student record code and already struggling converting it from C to C++ . But thanks for sharing your code

+2

@Martin ok I'll change them according to what you have said..Thank you so much for inspiring me though

+2

Writing the issue a book routine. The task actually states that when a book is issued you are supposed to decrement the count "If we issue a book, then its number gets decreased by 1 and if we add a book, its number gets increased by 1". I presume that this is for the case where multiple copies of a book are held. However, for the purpose of this learning exercise we will simply mark the book as issued. To keep the calling convention, and function structure, consistent with your other functions we will pass the array to this function, request the accession number of the book, and mark it as issued. Here is one solution to the problem. Note the break to exit the for loop once the accession number is found. Since each acquisition has a unique accession number there is no point in continuing through the loop if we have found the book. void issue_a_book(struct book b[]) //issuing a book { int num; int found = 0; cout << "\nEnter the accession number of the book: "; cin >> num; for(int i=0;i<counting; i++) { if(b[i].an == num){ b[i].issued = 1; found = 1; break; } } if(!found){ cout << "\nNo such book." << endl; } } Notice that we do not need to use cin >> ws here. This is because we are using cin >> to read a number, not a line of text, so it will automatically skip whitespace. We also need to update our call to the function from the switch case statement. issue_a_book(b); Your code should now in good shape with all features working.

+2

Time for a little refactoring of the code. Code refactoring is the process of restructuring software source code with the purpose to improve its internal structure and non-functional features. At the same time, its external behaviour remains unchanged. If you look at your code you will notice that the author, title, and displaybook routines all have the same code for printing out a book. This is known as WET (Write Everything Twice) code, or Thrice in this case. What we want is DRY (Don't Repeat Yourself) code. To do this we will write a bookinfo() function that prints a single book entry to the screen. We will then call this function from the author, title, and displaybook functions. This ensures a consistent display of the information across all routines. It also makes it simple to change the display format by editing only one function. The bookinfo function takes a single book structure as its only argument. void bookinfo(struct book b) { cout << "Accession number: " << b.an << "\nTitle: " << b.title << "\nAuthor: " << b.author << "\nStatus: "; if (b.issued == 0) { cout << "in stock" << endl; } else { cout << "out on loan" << endl; } cout << endl; } The displaybook function then becomes: void displaybook(struct book b[]) //for displaying { cout << endl; for (int i = 0; i < counting; i++) { bookinfo(b[i]); } } The author function if statement becomes: if (strcmp(name, b[i].author) == 0) { //comparing cnt++; bookinfo(b[i]); } The title function if statement becomes: if (strcmp(t, b[i].title) == 0) { //comparing cnt++; bookinfo(b[i]); } Which is much cleaner and simpler code.

+1

Ramisa Fariha Here's a C code I've made based on your requirements. This code was made in an hour, so it might contain bugs. Here's the code: https://code.sololearn.com/cpV0hiTq4R5a/?ref=app

+1

Ramisa Fariha Including the structure in a static array of such a size is bad practice. You may use a dynamic array instead, as speed isn't a concern here for such an application.

+1

Ramisa Fariha No problems. I had coded it in C as I don't know much about C++.

+1

How could you post your code like this insted of text

0

The question is: Let us work on the menu of a library. Create a structure containing book information like accession number, name of author, book title and flag to know whether book is issued or not. Create a menu in which the following can be done. 1 - Display book information 2 - Add a new book 3 - Display all the books in the library of a particular author 4 - Display the number of books of a particular title 5 - Display the total number of books in the library 6 - Issue a book (If we issue a book, then its number gets decreased by 1 and if we add a book, its number gets increased by 1) (not taken from any book) practice question from codesdope.com

0

Hemax Go to the code playground,do/copy-paste your code there and save it..then go to your profile,copy the link of your code(on right click of your mouse) and then paste wherever you want to