Read file to class members.

I have managed to read a string to a class member. My problem is that i want to read to four different class members (one string, three int) In the .txt file they are separated by a tab (This could change if its easier to read line for line)

Do you have any suggestions how one would do this?

First i have a books.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  #pragma once
  #include <string>
  #include <iostream>

  class Book {
    std::string m_title;
    int m_isbn;
    int m_copies;
    int m_year;

  public:
    std::string setTitle(std::string title) {
        return m_title = title;
    }
    
    void setIsbn(int isbn) {
        m_isbn = isbn;
    }
    
    void setCopies(int copies) {
        m_copies = copies;
    }
    
    void setYear(int year) {
        m_year = year;
    }
    
    void getTitle() {
        std::cout << m_title << std::endl;
    }
    };


And i got the main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "books.h"

#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>


int main () {
    Book a1;
    
    
    std::string titleList{};
    std::ifstream file ("booklist.txt");
    if(file.is_open()) {
        while (getline(file,titleList))
            {
                a1.setTitle(titleList);
            }
            file.close();
        
    }
    
    a1.getTitle(); //Just prints the member.

    }
Possibly like this - which reads the file and displays it contents. Not tried as you haven't provided a sample file contents. Uses a space/tab separator and title can't include a space/tab. If the title has/can have a space, then a different file format/read method is needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

class Book {
	std::string m_title;
	int m_isbn {};
	int m_copies {};
	int m_year {};

public:
	void setTitle(const std::string& title) { m_title = title; }
	void setIsbn(int isbn) { m_isbn = isbn; }
	void setCopies(int copies) { m_copies = copies; }
	void setYear(int year) { m_year = year; }

	std::string getTitle() const { return m_title; }
	int getIsbn() const { return m_isbn; }
	int getCopies() const { return m_copies; }
	int getYear() const { return m_year; }

	friend std::istream& operator>>(std::istream& is, Book& bk)
	{
		return is >> bk.m_title >> bk.m_isbn >> bk.m_copies >> bk.m_year;
	}

	friend std::ostream& operator<<(std::ostream& os, const Book& bk)
	{
		return os << bk.m_title << "  " << bk.m_isbn << "  " << bk.m_copies << "  " << bk.m_year;
	}
};

int main()
{
	std::ifstream file("booklist.txt");

	if (!file)
		return (std::cout << "Cannot open file\n"), 1;

	std::vector<Book> books;

	for (Book bk; file >> bk; books.emplace_back(bk));

	for (const auto& b : books)
		std::cout << b << '\n';

	std::cout << '\n';
}

Last edited on
Since you can change your input file structure I would recommend using delimited file structure. The delimiter can be anything that won't appear in your "normal" data. Examples of delimiters: new line character, tab character, comma, semi-colon, tilde, etc.

Example using semi-colon:

1
2
3
multi-word title;isbn;copies;year published
Book 1;9834823;34;1929
Book;948736723;938;2145


Note the header line is not really required but is often present for documentation.
Thank you!

Why is it you declare const at the "int getIsbn()" ?
I have not seen friend, what is that? You build upon them later in the main.
Any member function that doesn't change the member data is specified as const so that these methods will work on an object defined as const.

friend means that the specified function can access private variables etc.

The operators >> and << are overloaded for the Book class so that you can read/write one record of type Book with just one usage of >> or << (like you can use >> << with std::string etc).
Since you can change your input file structure I would recommend using delimited file structure. The delimiter can be anything that won't appear in your "normal" data. Examples of delimiters: new line character, tab character, comma, semi-colon, tilde, etc.


How would i implement that in code?

friend means that the specified function can access private variables etc.


Should i consider this as good practice since you generally (if i understand correctly) don't want to access the private members directly (maybe a friend is indirectly?)
How would i implement that in code?


1
2
3
4
5
6
	friend std::istream& operator>>(std::istream& is, Book& book)
	{
                char delim;
		std::getline(is, book.m_title, ';');
                is >> book.m_isbn >> delim >> book.m_copies >> delim >> book.m_year;
	}


By the way I would probably make the ISBN a string instead of an int.

So in this case the text file would be text and numbers with a ; between them to read it into the class members correctly?
This is what i come up with without dwelling deeper in friends. This works and it will print correctly when i am using the getters (yeah the should just return, i will fix that)

So obviously this is not the sharpest of code, what can i do to make it more efficient?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    int main () {
    Book a1;
    
    std::string isbnList{};
    int copiesList{};
    int yearList{};
    std::string titleList{};
    
    std::ifstream file ("booklist.txt");
    if(file.is_open()) {
        getline(file,titleList);
        getline(file, isbnList);
        file >> copiesList >>  yearList;
        a1.setTitle(titleList);
        a1.setIsbn(isbnList);
        a1.setCopies(copiesList);
        a1.setYear(yearList);
        
        file.close();
        
    }
    
    a1.getTitle();
    a1.getIsbn();
    a1.getCopies();
    a1.getYear();
Its fine, but one idea...
you could make a class method that does the file work. that gets rid of the calls to setters since you could then read directly into the class members.

Last edited on
Yes i intend to, this is one part of a bigger program that simulates a library. Thanks for all the help!
Topic archived. No new replies allowed.