Write a program to take input for n book records from user and write those book records in a file named: ”record”, whose price is less than INR 500 . Program should also perform random access in the file, after taking input for a particular record number to read and it should also perform random record overwriting after taking input of new record and the record number to overwrite. After overwriting record, display all records on the screen [Attributes of book: Book_id, Book_price, Book_name, Book_author_name]
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
const std::string RECORDS_FILE = "record";
const int PRICE_CEILING = 500;
class Book {
private:
std::string id = "";
float price = 0;
std::string name = "";
std::string author_name = "";
std::string readAttribute(std::string& str, int& i) {
std::string result;
int size = str.size();
// Skip leading spaces
for (; i < size && str[i] == ' '; ++i);
for (; i < size && str[i] != ';'; ++i) {
result += str[i];
}
++i;
// Remove trailing spaces
int j = 0;
for (int k = result.size() - 1; k >= 0 && result[k] == ' '; ++j, --k);
if (j > 0) result.assign(result, 0, result.size() - j);
return result;
}
public:
Book() {}
// Construct object from string record
Book(std::string& str) {
int i = 0;
id = readAttribute(str, i);
// atof() function (for converting string to float) accepts const char* parameter,
// so we should get string's raw pointer by calling c_str() method
price = atof(readAttribute(str, i).c_str());
name = readAttribute(str, i);
author_name = readAttribute(str, i);
}
friend std::ostream& operator <<(std::ostream& os, const Book& book) {
os << "id " << book.id << "\nprice " << book.price << "\nname " << book.name << "\nauthor " << book.author_name << '\n';
return os;
}
std::string getId() {
return id;
}
float getPrice() {
return price;
}
std::string getName() {
return name;
}
std::string getAuthor() {
return author_name;
}
};
Book getBook(std::string& line) {
// Skip the index of record (assuming it is correct because we wrote it ourselves)
int i = 0;
int size = line.size();
for (; i < size && line[i] != ')'; ++i);
++i;
return Book(line.assign(line, i, line.size() - i));
}
std::vector<Book> getBooks() {
std::ifstream is(RECORDS_FILE);
std::vector<Book> books;
std::string line;
for (std::getline(is, line); is; std::getline(is, line)) {
books.push_back(getBook(line));
}
return books;
}
void saveRecords(std::ofstream& os, std::vector<Book>& books) {
int size = books.size();
for (int i = 0; i < size; ++i) {
if (i) os << '\n';
os << i + 1 << ") " << books[i].getId() << "; " << books[i].getPrice() << "; " << books[i].getName() << "; " << books[i].getAuthor();
}
}
int main(int argc, char** argv) {
if (argc == 1) {
int n;
std::cout << "Enter the number of books: ";
std::cin >> n;
std::ofstream os(RECORDS_FILE);
std::cout << "Enter book data, each book in the following format:\n"\
"<book_id>; <book_price>; <book_name>; <book_author_name>\n";
std::string line;
// Remove newline character from input buffer
std::getchar();
std::vector<Book> books;
for (int i = 1; i <= n; ++i) {
std::cout << "Enter book " << i << " data:\n";
std::getline(std::cin, line);
Book book(line);
if (book.getPrice() < PRICE_CEILING) {
books.push_back(book);
}
}
saveRecords(os, books);
std::cout << "Data is saved to file '" << RECORDS_FILE << "'\n";
}
else {
std::string option = std::string(argv[1]);
if (argc == 2 && option == "help") {
std::cout << "Options:\n";
std::cout << "#no options# Set up book records\n";
std::cout << "get <record number> Get book record with sequence number <record number>\n";
std::cout << "update <record number> Update book record with sequence number <record number>\n";
}
else if (option == "get" || option == "update") {
if (argc != 3) {
std::cerr << "Using with '" << option << "' option: " << option << " <record number>\n";
return 1;
}
std::vector<Book> books = getBooks();
int index = atoi(argv[2]);
int size = books.size();
if (index <= 0 || index > size) {
std::cerr << "Record number must be integer from 1 to " << size << '\n';
return 1;
}
if (option == "get") {
std::cout << books[index - 1];
}
else {
std::cout << "Enter book data in the following format\n"\
"<book_id>; <book_price>; <book_name>; <book_author_name>\n";
std::string line;
std::getline(std::cin, line);
books[index - 1] = Book(line);
std::ofstream os(RECORDS_FILE);
saveRecords(os, books);
std::cout << "Updated records:\n";
for (int i = 0; i < books.size(); ++i) {
std::cout << "----------------\n";
std::cout << books[i];
}
}
}
}
return 0;
}
Type 'help' option to see usage information:
Setting up records:
After this step content of the file "record" looks like this:
1) a1; 480; Harry Potter and the Philosopher's Stone; J. K. Rowling
2) b2; 460; Harry Potter and the Chamber of Secrets; J. K. Rowling
Third book data is not saved because its price is 510 >= 500
Getting record by it's number:
Updating record:
File contents is updated accordingly:
1) a1; 480; Harry Potter and the Philosopher's Stone; J. K. Rowling
2) c3; 499; Harry Potter and the Prisoner of Azkaban; Joanne Rowling
Comments
Leave a comment