-
April 18th, 2014, 08:36 PM
#1
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..
-
April 19th, 2014, 06:51 AM
#2
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)
-
April 19th, 2014, 10:54 AM
#3
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 ...
-
April 19th, 2014, 11:28 AM
#4
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)
-
April 21st, 2014, 11:00 PM
#5
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
-
April 22nd, 2014, 11:21 AM
#6
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)
-
April 22nd, 2014, 10:37 PM
#7
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|