CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Apr 2014
    Posts
    25

    reading from a txt file that's a record

    Hello codeguru,

    I'm working on a program using class booktype... to hold information about various books that I have saved on a txt file. Each object of the class book type holds the author, publisher, ISBN, number of copies in stock.



    I am still very much new at c++ and not exactly sure how to get in info from the file I've made earlier..


    Code:
    #include<iostream>
    #include<iomanip>
    #include<string>
    #include<cstring>
    #include<fstream>
    using namespace std;
    
    class bookType
    {
    public:
        string title;
        string author;
        string publisher;
        int ISBN;
        string inStock;
    
    int main()
    {
        bookType listed;
    
        fstream books("books.txt", ios::out | ios::in | ios::binary);
        if(!books)
        {
                    cout<<"Error opening data file.\n";
                    return 0;
        }
    
              while(!books.eof())
        {
            cout<<listed.title<<endl;
            cout<<listed.author<<endl;
            cout<<listed.publisher<<endl;
            cout<<listed.ISBN<<endl;
            cout<<listed.inStock<<endl;
            books.read(reinterpret_cast<char *>(&listed),sizeof(listed));
        }books.close();
        return 0;
    }
    also the text file is formatted where after I've entered the author's name I then hit return, then publisher then I hit return, ISBN then return, and so forth does that effect the program?

    as for my txt file this is what I have
    Code:
    Moby Dick
    Sebastian Armesto
    Oberoson Books Ltd
    0001
    201
    The Scarlet Letter
    Nathaniel Howthorne
    eBookit.com
    0002
    65
    Dracula
    Bram Stroker
    Archibald Constable and Company
    0003
    103
    Lord of the files
    William Golding
    Faber and Faber
    0004
    65
    To Kill a Mockingbird
    Harper Lee
    J.B. Lippincott & Co.
    0005
    26
    as always your help is very much appreciated thanks..

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: reading from a txt file that's a record

    Code:
    books.read(reinterpret_cast<char *>(&listed),sizeof(listed));
    This will only read sizeof(listed) bytes from the file which is not what you want. The size of the class is different from the size of the data on the file as the class stores some of the data in dynamic storage (eg string).

    One way of doing this is
    Code:
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <fstream>
    using namespace std;
    
    class bookType
    {
    private:
    	string title;
    	string author;
    	string publisher;
    	string ISBN;
    	int inStock;
    
    public:
    	bool read(ifstream& books);
    	void display();
    };
    
    bool bookType::read(ifstream& books)
    {
    const int noLines = 5;
    
    string lines[noLines];
    
    	for (int i = 0; i < noLines; ++i)
    		getline(books, lines[i]);
    
    	if (books.good())
    	{
    		title = lines[0];
    		author = lines[1];
    		publisher = lines[2];
    		ISBN = lines[3];
    		inStock = atoi(lines[4].c_str());
    	}
    
    	return books.good();
    }
    
    void bookType::display()
    {
    	cout << title << endl;
    	cout << author << endl;
    	cout << publisher << endl;
    	cout << ISBN << endl;
    	cout << inStock << endl;
    	cout << endl;
    }
    
    int main()
    {
    ifstream books("books.txt");
    
    	if (!books.is_open())
    	{
    		cout << "Error opening data file.\n";
    		return 1;
    	}
    
    	while (books.good())
    	{
    		bookType listed;
    
    		if (listed.read(books))
    			listed.display();
    
    	}
    
    	books.close();
    	return 0;
    }
    This has class functions read to read one record from the file and display to show the record. Other required operations for this class can then be implemented as additional class functions.

    As a line can contain one or more spaces, you can't just use simple file extraction to read the data as that only reads text upto a white-space char (linefeed, tab, space etc). You need to read the text file one line at a time.
    Last edited by 2kaud; April 19th, 2014 at 06:59 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Apr 2014
    Posts
    25

    Re: reading from a txt file that's a record

    Thank you so much this is exactly what I wanted to do, thank for taking time in explaining what I was doing wrong and putting me on the right track. I still have much more programming to do with this because I have to add sorting ad searching functions I will definitely build using this code. Thanks again... now I have to go to work ...

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: reading from a txt file that's a record

    If you want to add sorting and searching then I would suggest that you read the whole file into a container such as a vector (http://www.cplusplus.com/reference/vector/vector/) and use STL to do the sorting and searching (http://www.cplusplus.com/reference/algorithm/)
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Apr 2014
    Posts
    25

    Re: reading from a txt file that's a record

    I have now created a second txt file called users and I need help in writing the code so that the program will search for the users name and after they found the users name, there information will come up (first last name, how much they spend and then I want to ask them what book they are looking for so the program will do a search for that title and display all the info for that book (title publisher how many is in stock).

    this what I have so far
    Code:
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <fstream>
    #include<iomanip>
    using namespace std;
    
    class bookType
    {
    private:
    	string title;
    	string author;
    	string publisher;
    	string ISBN;
    	int inStock;
    
    public:
    	bool read(ifstream& books);
    	void display();
    };
    
    bool bookType::read(ifstream& books)
    {
    const int noLines = 5;
    
    string lines[noLines];
    
    	for (int i = 0; i < noLines; ++i)
    		getline(books, lines[i]);
    
    	if (books.good())
    	{
    		title = lines[0];
    		author = lines[1];
    		publisher = lines[2];
    		ISBN = lines[3];
    		inStock = atoi(lines[4].c_str());
    	}
    
    	return books.good();
    }
    
    void bookType::display()
    {
    	cout << title << endl;
    	cout << author << endl;
    	cout << publisher << endl;
    	cout << ISBN << endl;
    	cout << inStock << endl;
    	cout << endl;
    }
    class memberType
    {
    private:
        string fname;
        string lname;
        int memberID;
        int booksBought;
        double amountSpent;
    public:
        bool read(ifstream& users);
        void display2();
    };
    bool memberType::read(ifstream& users)
    {
    const int noLines = 5;
    
    string lines[noLines];
    
    	for (int i = 0; i < noLines; ++i)
    		getline(users, lines[i]);
    
    	if (users.good())
    	{
    		fname = lines[0];
    		lname = lines[1];
    		memberID = atoi(lines[2].c_str());
    		booksBought = atoi(lines[3].c_str());
    		amountSpent = atoi(lines[4].c_str());
    	}
    
    	return users.good();
    }
    void memberType::display2()
    {
        cout << fname << endl;
        cout << lname << endl;
        cout << memberID << endl;
        cout << booksBought << endl;
        cout << amountSpent << endl;
    }
    char getChoice();               //prototype
    int main()
    {
      memberType member;
    
    ifstream users("users.txt"); //open file for members
    if (!users.is_open())
    {
        cout<<"Error opening user file.\n";
        return 1;
    }
    
    
    ifstream books("books.txt"); // open file for books
    
    	if (!books.is_open())
    	{
    		cout << "Error opening books file.\n";
    		return 1;
    	}
    
        //while(users.good())
    
            cout<< fixed << showpoint << setprecision(2);
            char selection;
            string search;
            string line;
            cout<<"Welcome to the Book Store"<<endl<<endl;
            cout<<"Select (N) to enter Name or (I) to enter ID Number"<<endl;
            selection = getChoice();
    
            switch(selection)
            {
            case 'n':
            case 'N': cout<< "Please enter your last Name"<<endl;
            cin>>search;
            break;
            case 'i':
            case 'I': cout<<"Please enter your ID Number"<<endl;
            cin >>search;
    }
    
    size_t pos;
    while(users.good())
      {
          getline(users,line); // get line from file
          pos=line.find(search); // search
          if(pos!=string::npos) // string::npos is returned if string is not found
            cout <<"welcome "<<search<<endl;
    
      }
    	books.close();
    	return 0;
    }
    char getChoice()
    {
        char letter;
        cin >> letter;
    
        while (letter != 'N' && letter != 'n' && letter != 'I' && letter != 'i')
        {
            cout <<"Enter N or I: ";
            cin>> letter;
        }
        return letter;
    }

    I believe I need to have something like this as a constructor but it needs to be edited so that it's actually getting info from a file:

    Code:
    int binary Search(const int array[], int size, int value)
    {
    
    in first=0,
    last =size -1,
    middle,
    position=-1;
    bool found =false;
    
    while(!found && first <= last)
    {
    middle=(first + last)/2;
    if (array[middle]==value)
       {
        found=true;
        position=middle;
        }
        else if (array[middle]>value)
              last=middle-1;
         else
          first=middle+1;
    }
    return position;
    }
    this is what I have in the additional txt file :

    Code:
    Donald
    Duck
    1111
    3 books
    25.00
    Micky
    Mouse
    1112
    5 books
    50.00
    Charlie
    Brown
    1113
    10 books
    100.00
    He
    Man
    1114
    7 books
    35.00
    She
    Ra
    1115
    20 books
    32.00
    George
    Jetson
    1117
    12 books
    23.00
    Brenda
    Starr
    1118
    43 books
    39.00
    Wonder
    Woman
    1119
    16 books
    24.00
    if it's possible... can you please help me clean up this code so it actually works and make sense...

    I know this is very basic for you guys but for me I'm still making sense of it.

    thanks for all your help

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: reading from a txt file that's a record

    Code:
    amountSpent = atoi(lines[4].c_str());
    should use atof() here as amountSpent is of type double.

    I've tidied up the code a bit and added a search on users for surname which displays the details of the name found. This will give you an idea for doing the other searches required. It is a simple linear search that starts at the beginning of the file and sequentially reads the data from the file until either a match is found or eof is reached. If there are multiple users with the same surname it will find the first. If all the data is read first into a container then other search methods could be used. Have fun!

    Code:
    #include <iostream>
    #include <string>
    #include <cstdlib>
    #include <fstream>
    #include <iomanip>
    using namespace std;
    
    class bookType
    {
    private:
    	string title;
    	string author;
    	string publisher;
    	string ISBN;
    	int inStock;
    
    public:
    	bool read(ifstream& books);
    	void display();
    };
    
    class memberType
    {
    private:
        string fname;
        string lname;
        int memberID;
        int booksBought;
        double amountSpent;
    
    public:
        bool read(ifstream& users);
        void display();
        bool search(ifstream& users, const string& surname);
    };
    
    bool bookType::read(ifstream& books)
    {
    const int noLines = 5;
    
    string lines[noLines];
    
    	for (int i = 0; i < noLines; ++i)
    		getline(books, lines[i]);
    
    	if (books.good())
    	{
    		title = lines[0];
    		author = lines[1];
    		publisher = lines[2];
    		ISBN = lines[3];
    		inStock = atoi(lines[4].c_str());
    	}
    
    	return books.good();
    }
    
    void bookType::display()
    {
    	cout << title << endl;
    	cout << author << endl;
    	cout << publisher << endl;
    	cout << ISBN << endl;
    	cout << inStock << endl;
    	cout << endl;
    }
    
    bool memberType::read(ifstream& users)
    {
    const int noLines = 5;
    
    string lines[noLines];
    
    	for (int i = 0; i < noLines; ++i)
    		getline(users, lines[i]);
    
    	if (users.good())
    	{
    		fname = lines[0];
    		lname = lines[1];
    		memberID = atoi(lines[2].c_str());
    		booksBought = atoi(lines[3].c_str());
    		amountSpent = atof(lines[4].c_str());
    	}
    
    	return users.good();
    }
    
    void memberType::display()
    {
        cout << fname << endl;
        cout << lname << endl;
        cout << memberID << endl;
        cout << booksBought << endl;
        cout << fixed << showpoint << setprecision(2) << amountSpent << endl;
    }
    
    bool memberType::search(ifstream& users, const string& surname)
    {
    	users.clear();
    	users.seekg(0, users.beg);
    
    bool found;
    
    	while ((found = read(users)) && (lname != surname));
    
    	return found;
    }
    
    int main()
    {
    ifstream users("users.txt"); //open file for members
    
    	if (!users.is_open())
    	{
    		cout<<"Error opening user file.\n";
    		return 1;
    	}
    
    ifstream books("books.txt"); // open file for books
    
    	if (!books.is_open())
    	{
    		cout << "Error opening books file.\n";
    		return 1;
    	}
    
    	cout << "Welcome to the Book Store" << endl << endl;
    
    	while (true)
    	{
    		cout << "Select (N) to enter Name, (I) to enter ID Number or (Q) to quit: ";
    
    		memberType memb;
    
    		string search;
    
    		char sel;
    
    		cin.clear();
    		cin >> sel;
    		cin.ignore(1000, '\n');
    
    		switch (tolower(sel))
    		{
    			case 'n':
    				cout << "Please enter your last Name: ";
    				cin >> search;
    				if (memb.search(users, search))
    					memb.display();
    				else
    					cout << "Name not found\n";
    
    				break;
    
    			case 'i':
    				cout << "Please enter your ID Number: ";
    				cin >> search;
    				break;
    
    			case 'q':
    				books.close();
    				users.close();
    				return 0;
    
    			default:
    				cout << "Invalid selection\n";
    		}
    	}
    }
    Last edited by 2kaud; April 22nd, 2014 at 11:25 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Apr 2014
    Posts
    25

    Re: reading from a txt file that's a record

    Thank you so much for your help. With a few minor edits I was able to get the program to run how I wanted and with a cleaner version.

    much obliged..

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured