Answer to Question #326252 in C++ for gayathri

Question #326252

: Write a program to write 5 book records in a file. 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. [Attributes of book: Book_id, Book_price, Book_name, Book_author_name]


1
Expert's answer
2022-04-10T03:12:36-0400
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


const int BOOKS_AMOUNT = 5;
const std::string RECORDS_FILE = "books.txt";


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) {
  for (int i = 0; i < BOOKS_AMOUNT; ++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) {
    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;
    std::vector<Book> books;
    for (int i = 0; i < BOOKS_AMOUNT; ++i) {
      std::cout << "Enter book " << i + 1 << " data:\n";
      std::getline(std::cin, line);
      books.push_back(Book(line));
    }
    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 5 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;
      }
      int index = atoi(argv[2]);
      if (index <= 0 || index > BOOKS_AMOUNT) {
        std::cerr << "Record number must be integer from 1 to " << BOOKS_AMOUNT << '\n';
        return 1;
      }
      if (option == "get") {
        std::ifstream is(RECORDS_FILE);
        // Skip records before the one we are interested in
        std::string line;
        for (int i = 0; i < index; ++i, std::getline(is, line));
        std::cout << getBook(line);
      }
      else {
        std::vector<Book> books = getBooks();
        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 << "Record updated\n";
      }
    }
  } 
  return 0;
}

Type 'help' option to see usage information



Setting up records:



After this step content of the file "books.txt" looks like this:

1) a1; 100; Harry Potter and the Philosopher's Stone; J. K. Rowling

2) b2; 98; Harry Potter and the Chamber of Secrets; J. K. Rowling

3) c3; 103; Harry Potter and the Prisoner of Azkaban; J. K. Rowling

4) d4; 96; Harry Potter and the Goblet of Fire; J. K. Rowling

5) e5; 93; Harry Potter and the Order of the Phoenix; J. K. Rowling


Getting record by it's number:



Updating record:



File contents is updated accordingly:

1) a1; 100; Harry Potter and the Philosopher's Stone; J. K. Rowling

2) b2; 98; Harry Potter and the Chamber of Secrets; J. K. Rowling

3) c3; 103; Harry Potter and the Prisoner of Azkaban; J. K. Rowling

4) d4; 96; Harry Potter and the Goblet of Fire; J. K. Rowling

5) f6; 95; Harry Potter and the Half-Blood Prince; Joanne Rowling


Need a fast expert's response?

Submit order

and get a quick answer at the best price

for any assignment or question with DETAILED EXPLANATIONS!

Comments

No comments. Be the first!

Leave a comment

LATEST TUTORIALS
New on Blog
APPROVED BY CLIENTS