I'm working on this program that is to help manage a DVD rental store. What I have to do is take a text that contains info about DVD etc:
Mean girls; comedy; PG; 2009; Regina George; 12.07.2015;
The Conjuring; Horror; R; 2013; Sara Johnson; 16.05.2016;
Pokemon 2000; Kids; G; 2000; Ash Katchem; 15.04.2016;
etc..
And then takes this information and then reads it into an array and from there the array is read into the struct and then displayed in proper order like so:
Name: Mean Girls
Genre: Comedy
Rating: PG
etc...
This is my code so far:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
struct dvd{
string name;
string genre;
string rating;
string released;
string renter;
string rentday;
void print();
bool read(ifstream & file);
};
void dvd::print(){
cout <<"Title: " << name << endl;
cout <<"Genre: " << genre << endl;
cout << "Rating: " << rating << endl;
cout << "Release date: " << released << endl;
cout << "Name of renter: " << renter << endl;
cout << "Date rented: " << rentday << endl;
}
bool dvd::read(ifstream & file)
{
getline(file, name, ';');
getline(file, genre, ';');
getline(file, rating,';');
getline(file, released, ';');
getline(file, renter, ';');
getline(file, rentday, ';');
return file.good();
}
int main() {
vector<dvd> dvds;
dvd dvd1;
ifstream file("DVD.txt");
if(! file.is_open()){
cout << "Failed to find input file" << endl;
return 1;
}
while(dvd1.read(file))
{ dvds.push_back(dvd1);
}
dvd1.print();
return 0;
}
So what I would like to do is have read the text file into the Array and from there read the Array into the struct. So instead of the text file reading into the vector I need it to read into the array and from there read the first line of the array (dvdArray[1]) into struct dvd and then print out that information using print function and then loop that until dvdArray[10] is read into struct dvd!
Thank you so much for your help! :)
Change
bool dvd::read(ifstream & file)
to
bool dvd::read(istream & file)
No other changes to its contents are required.
Then, take each line and put it into a std::istringstream, then pass it to dvd::read.
You should be able to figure out the rest on your own.
For simple reading from and writing to file, I would suggest overload << and >> for your struct class, in order to make the code easy to serialize and de-serialize in a readable fashion.
friend std::ostream& operator<< (std::ostream& stream, const dvd& dvdObj)
{
// your output stuff
// stream <<"Title: " << dvdObj.name << endl;
// ...
return stream;
}
friend std::istream& operator>> (std::istream& stream, dvd& dvdObj)
{
// your output stuff
// getline(stream, dvdObj.name, ';');
// ...
return stream;
}
Then,
// look for std::copy for reading directly into vector ... else
while( file >> dvd1 )
{
dvds.push_back(dvd1);
}
And,
for( const auto& dvd1: dvds )
{
std::cout << dvd1 ;
}
Related
I trying to write a function which searches for an ID and prints the book name and author name. I have been able to match the ID, however not able to properly print the book and author name. Text file is stored as such:
ID
book name
author name
Following is the code for my search function:
void searching() {
string search, id, name;
ifstream myfile("books.txt");
bool found = false;
string line;
cout << "\nEnter ID to search : ";
cin >> search;
int srchlen = search.length();
if(myfile.is_open()) {
while(getline(myfile, line)) {
id = line.substr(0, srchlen);
if(id == search) {
found = true;
break;
} else {
found = false;
}
}
if(found == true) {
name = line;
cout << "ID\tNAME\tAUTHOR\n";
cout << name;
} else {
cout << "ID doesnt exist";
}
}
}
Here is how the text file looks like (there is a blank line between each book):
98
crime and punishment
Dostoevsky
70
The Da Vinci Code
Dan Brown
So there's a logical flaw in your code that makes it harder to do what you want. The book data is stored on three separate lines, but your code reads one line at a time. Logically you should be reading three lines at a time. By doing this you'll have all the information available for one book at the same time.
Like this
string id, title, author;
while (getline(myfile, id) && getline(myfile, title) && getline(myfile, author)) {
string blank;
getline(myfile, blank); // skip the blank line between books
id = id.substr(0, srchlen);
if (id == search) {
found = true;
break;
} else {
found = false;
}
}
if (found == true) {
cout << "ID\tNAME\tAUTHOR\n";
cout << id << ' ' << title << ' ' << author << '\n';;
} else {
cout << "ID doesnt exist";
}
Note that reading the blank line is not part of the while condition. We don't want not to consider a book just because it wasn't followed by a blank line. This might happen at the end of the file for example.
To make it easier to deal with the data, I recommend putting the information about a book into a class (struct) and to add operators for reading/writing one book at a time from/to an istream/ostream.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <string>
struct Book {
std::string id;
std::string title;
std::string author;
};
// operator for reading one book title from any istream
std::istream& operator>>(std::istream& is, Book& b) {
std::getline(is, b.id);
std::getline(is, b.title);
std::getline(is, b.author);
// ignore the blank line between books in the file:
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return is;
}
// operator for writing one book title to any ostream
std::ostream& operator<<(std::ostream& os, const Book& b) {
return os << b.id << '\n' << b.title << '\n' << b.author << "\n\n";
}
int main() {
std::string search;
std::cout << "\nEnter ID to search : ";
std::cin >> search;
if(std::ifstream myfile("books.txt"); myfile) {
Book book;
// read one book at a time from the stream using the added
// operator>>
while(myfile >> book) {
if(book.id == search) {
// book found, write it to cout using the added
// operator<<
std::cout << book;
break;
}
}
}
}
By taking some advantages of C++ such as vector, you can make the code easier:
#include <iostream>
#include <vector>
#include <fstream>
const char *fileName = "books.txt";
// structure of the file
struct book {
int ID;
std::string author;
std::string bookName;
};
int main(void) {
std::ifstream file(fileName); // to read the file
std::vector<book> vec; // to find the content required
int ID; // the ID to find
book temp; // temporary 'book' to insert in vector
bool found = false;
// if the file was unable to open
if (!file.is_open()) {
std::cout << "Unable to open the file." << std::endl;
return -1;
}
// getting the content of the file
while (file >> temp.ID >> temp.bookName >> temp.author)
vec.push_back(temp);
std::cout << "Enter the ID to find: ";
std::cin >> ID;
// matching the IDs
for (size_t i = 0, len = vec.size(); i < len; i++)
// prints when ID asked to show is present in the file
if (vec[i].ID == ID) {
std::cout << "ID: " << vec[i].ID << " | Author: "
<< vec[i].author << " | Name: " << vec[i].bookName;
found = true;
break;
}
if (!found)
std::cout << "The ID does not exist." << std::endl;
return 0;
}
Supposing the books.txt contains:
// FORMAT: ID _ Book _ Author
10 BookABC John
20 BookXYZ Ben
30 CodingBook Rock
Then the output would be something like:
Enter the ID to find: 30
ID: 30 | Author: Rock | Name: CodingBook
i wrote a code for searching a string in a file. Actually, i put my data in my file like this:
alex booth,15,1 (fullname with space, age, id).
There isn't any problem with saving data in the file, i got a big problem in searching for a string in that file.
For example, i want to search in the file for a name like "alex booth", but it seems the search can't find that the word despite of being available. I can guess that there's a problem with saving the name with space, but i don't know what should i do for fixing it. As the matter of fact, i don't know exactly how can we search for a name with blank space within it.
Here is my code:
using namespace std;
struct product{
string name;
int price, id;
};
int main() {
product myProduct;
ofstream productList("product.csv", ios::app | ios::out);
getline(cin, myProduct.name);
cin >> myProduct.price;
cin >> myProduct.id;
productList << myProduct.name << ',' << myProduct.price << ',' << myProduct.id << endl;
productList.close();
cout << "----" << endl;
system("pause");
ifstream checkList("product.csv");
string dummy;
string check;
cin.ignore();
getline(cin, check);
while (!checkList.eof()) {
while (checkList >> myProduct.name >> myProduct.price >> myProduct.id) {
if (myProduct.name == check) {
cout << "Product Name: " << myProduct.name <<
" - Product's Price: " << myProduct.price <<
" - ID Number: " << myProduct.id << endl;
}
}
}
checkList.close();
return 0;
}
When you are reading lines from the file, you are not taking the commas into account at all, then operator>> fails inside your inner while loop.
Also, your outer while loop is wrong, too.
Try something more like this instead:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <limits>
#include <cstdlib>
using namespace std;
struct product{
string name;
int price, id;
};
int main() {
product myProduct;
cout << "Enter product name: ";
getline(cin, myProduct.name);
cout << "Enter product price: ";
cin >> myProduct.price;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter product id: ";
cin >> myProduct.id;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
ofstream productList("product.csv", ios::app);
productList << myProduct.name << ',' << myProduct.price << ',' << myProduct.id << std::endl;
productList.close();
cout << "----" << endl;
system("pause");
cin.ignore();
cout << "Enter name to look for: ";
string check;
getline(cin, check);
ifstream checkList("product.csv");
string line;
char comma;
while (getline(checkList, line)) {
istringstream iss(line);
if (getline(iss, myProduct.name, ',') && (iss >> myProduct.price >> comma >> myProduct.id) && (comma == ',')) {
if (myProduct.name == check) {
cout << "Product Name: " << myProduct.name <<
" - Product's Price: " << myProduct.price <<
" - ID Number: " << myProduct.id << endl;
}
}
}
checkList.close();
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <limits>
#include <cstdlib>
using namespace std;
struct product{
string name;
int price, id;
};
istream& getInt(istream &in, int &value)
{
string str;
if (getline(in, str, ',')) {
try {
value = stoi(str);
}
catch (...) {
in.setstate(ios::failbit);
}
}
return in;
}
int main() {
product myProduct;
cout << "Enter product name: ";
getline(cin, myProduct.name);
cout << "Enter product price: ";
cin >> myProduct.price;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter product id: ";
cin >> myProduct.id;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
ofstream productList("product.csv", ios::app);
productList << myProduct.name << ',' << myProduct.price << ',' << myProduct.id << std::endl;
productList.close();
cout << "----" << endl;
system("pause");
cin.ignore();
cout << "Enter name to look for: ";
string check;
getline(cin, check);
ifstream checkList("product.csv");
string line;
while (getline(checkList, line)) {
istringstream iss(line);
if (getline(iss, myProduct.name, ',') && getInt(iss, myProduct.price) && getInt(iss, myProduct.id)) {
if (myProduct.name == check) {
cout << "Product Name: " << myProduct.name <<
" - Product's Price: " << myProduct.price <<
" - ID Number: " << myProduct.id << endl;
}
}
}
checkList.close();
return 0;
}
I would like to propose an additional solution, a “more” modern C++ and object oriented solution. And, a full working solution.
In C++ we usually put data, and functions operating on that data, into an object, a class. The class and only the class should know how to handle its data.
So in your example the “id,” "name" and “price” are attributes for an object, and extracting them from a std::istream or inserting them into a std::ostream should be only known by that object and handled by it.
As a consequence, we create a class/struct, define 3 data members, namely the "id", “name” and "price" as a unsigned long",std::stringand the “price” as adouble````. Then, we overwrite the extractor operator (>>) and the inserter operator. The extractor operator is a little bit tricky, since we first read a complete line and then split it into tokens.
In C++ your file structure is called CSV (Comma Separated Value). And, reading this is a standard task. First, read the complete line, then, using a given delimiter, extract the tokens of that string. The “splitting” is also called “tokenizing” and C++ has a dedicated functionality for that purpose: std::sregex_token_iterator.
This thing is an iterator. For iterating over a string, hence “sregex”. The begin part defines, on what range of input we shall operate, then there is a std::regex for what should be matched / or what should not be matched in the input string. The type of matching strategy is given with last parameter.
1 --> give me the stuff that I defined in the regex and
-1 --> give me that what is NOT matched based on the regex.
We can use this iterator for storing the tokens in a std::vector. The std::vector has a range constructor, which takes 2 iterators as parameter, and copies the data between the first iterator and 2nd iterator to the std::vector. The statement
std::vector tokens(std::sregex_token_iterator(line.begin(), line.end(), re, -1), {});
defines a variable “tokens” as a std::vector and uses the so called range-constructor of the std::vector. Please note: I am using C++17 and can define the std::vector without template argument. The compiler can deduce the argument from the given function parameters. This feature is called CTAD ("class template argument deduction").
Additionally, you can see that I do not use the "end()"-iterator explicitly.
This iterator will be constructed from the empty brace-enclosed initializer list with the correct type, because it will be deduced to be the same as the type of the first argument due to the std::vector constructor requiring that.
Then, after reading the line and splitting it into tokens, we check, if we have exactly 3 tokens and then store the result as "id", “name” and “price”. So, overall, a very simple operation.
in main I put some example driver code. For example, you can see that I store a new product into the file with a simple
productFile << product;
statement. And reading the complete CSV file and parsint it, is done with a simple one-liner:
std::vector productList(std::istream_iterator<Product>(productFile), {});
Finding an element is just using std::find_if.
Please see below a complete example:
(I put many comments and empty lines to make the code more readble.)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <fstream>
#include <regex>
const std::string delimiter(",");
const std::regex re(delimiter.c_str());
struct Product {
// Data
unsigned long id{};
std::string name{};
double price{};
// Member Functions
// Simple Inserter.
friend std::ostream& operator << (std::ostream& os, const Product& product) {
// Unfortunately the ostream_joiner does not work on my system . . .
return os << product.id << delimiter << product.name << delimiter << product.price << "\n";
}
// simple Extractor
friend std::istream& operator >> (std::istream& is, Product& product) {
// Read a complete line
if (std::string line{}; std::getline(is,line)) {
// Convert line into tokens. Split any number of csv columns. One-liner
std::vector tokens(std::sregex_token_iterator(line.begin(), line.end(), re, -1), {});
// if we have read 3 tokens as expected
if (3 == tokens.size()) {
// Assign values to data member
product.id = std::strtoul(static_cast<std::string>(tokens[0]).c_str(), nullptr, 10);
product.name = tokens[1];
product.price = std::strtod(static_cast<std::string>(tokens[2]).c_str(), nullptr);
}
}
return is;
}
};
int main() {
const std::string filename{ "r:\\product.csv" };
// First, we ask the user to enter product data
std::cout << "\nEnter product ID, product name and product price in one line separated by comma:\n";
// Get input
if (Product product; std::cin >> product) {
// Save the user data in a file
if (std::ofstream productFile(filename,std::ios::app); productFile) {
// Write to output file stream
productFile << product;
}
else {
std::cerr << "\n\n***Could not write to file\n\n";
}
}
// Now test the search function
// Get the name to look for
std::cout << "\n\nEnter a name to look for:\n ";
if (std::string name{}; std::getline(std::cin, name)) {
// Open the file for reading
if (std::ifstream productFile(filename); productFile) {
// Read the complete file. One-liner
std::vector productList(std::istream_iterator<Product>(productFile), {});
// Search for the name
auto result = std::find_if(productList.begin(), productList.end(), [&name](const Product& p) { return p.name == name; });
// If found, print result
if (result != productList.end())
std::cout << "Found: " << *result <<"\n\n";
else
std::cout << "Name '" << name <<"' not found\n\n";
// For the fun of it: Show all data
std::copy(productList.begin(), productList.end(), std::ostream_iterator<Product>(std::cout));
}
else {
std::cerr << "\n\n***Could not read from file\n\n";
}
}
return 0;
}
I hope that gives you an idea, how such a problem can be solved. Of course there are tons of other solutions. . .
I'm creating a program that reads the author, title, and number of volumes from a file and prints out labels,
(ex.
Adams
A Complete History of the World
Volume 1 of 10
Adams
A Complete History of the World
Volume 2 of 10 etc.)
To make it read properly and not infinitely loop, I had to change all of my variable to string. However, for future reference to the volume number, I need it to be int so I can compare the amount.
My ideas for furthering the code with a do-while loop are commented in to show why I'd like vnum to have int value.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream fin;
string author;
string title;
string vnum;
int counter=1;
fin.open("publish.txt", ios::in);
while (!fin.eof())
{
getline(fin, author);
getline(fin, title);
getline(fin, vnum);
//do
//{
cout << author << endl;
cout << title << endl;
cout << "Volume " << counter << " of " << vnum << endl;
cout << endl;
//counter++;
//} while(counter < vnum);
}
fin.close();
return 0;
}
File I'm reading from:
Adams
A Complete History of the World
10
Samuels
My Life of Crime
2
Baum
Wizard Stories
6
First of all, avoid use of
while (!fin.eof())
See Why is “while ( !feof (file) )” always wrong? to understand the problems it would cause.
Coming to your task, I would suggest:
Create a struct to hold the data.
Add a function to read all the members of the struct from a std::istream.
Add a function to write all the members of the struct to a std::ostream.
Simplify main to use the above.
Here's what I suggest:
struct Book
{
std::string author;
std::string title;
int volume;
};
std::istream& operator>>(std::istream& in, Book& book);
std::ostream& operator<<(std::ostream& out, Book const& book);
That will help simplify main to:
int main()
{
ifstream fin;
Book book;
// Not sure why you would need this anymore.
int counter=1;
fin.open("publish.txt", ios::in);
while ( fin >> book )
{
cout << book;
++counter;
}
return 0;
}
The functions to read and write a Book can be:
std::istream& operator>>(std::istream& in, Book& book)
{
// Read the author
getline(in, book.author);
// Read the title
getline(in. book.title);
// Read the volume
in >> book.volume;
// Ignore rest of the line.
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return in;
}
std::ostream& operator<<(std::ostream& out, Book const& book)
{
out << book.author << std::endl;
out << book.title << std::endl;
out << book.volume << std::endl;
return out;
}
I'm new to C++. I have a file named test.txt with following data
2
Salman Khan
20 100000 4.75 1000
Aamir khan
30 200000 5.25 1000
where
the first line is the number of user records,
the second line is Name separated by space, and
the third line consists of years, amount, rate, amount per month that the user is qualified.
I want to calculate formula and show into a table.
so far i've done is as follow:
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
struct Customers
{
char first_name[50];
char last_name[30];
int years;
float amount;
float interest_rate;
float amount_per_month;
};
int main() {
Customers cus;
int sum = 0;
string x,line;
string fileName = "";
ifstream inFile;
string firstLine;
int numberOfCustomers = 0;
cout << "Enter File Name: \n";
cin >> fileName;
cout << "Reading File : '"+ fileName+"'" << endl;
inFile.open(fileName);
if (!inFile) {
cout << "Unable to open file";
exit(1); // terminate with error
}
if (inFile.good())
{
getline(inFile, firstLine);
numberOfCustomers = stoi(firstLine);
cout << "Available Loan Applications : " << numberOfCustomers << endl;
}
while (inFile >> x) {
cout << x << endl;
cin >> cus.first_name;
}
inFile.close();
return 0;
}
I'm trying to store data to structure and then calculate, i need help in storing data to structure.
You can use stream extraction and stream insertion operators to read/write custom datatypes:
#include <cstddef> // std::size_t
#include <cstdlib> // EXIT_FAILURE
#include <iterator> // std::istream_iterator<>
#include <vector> // std::vector<>
#include <string> // std::string
#include <fstream> // std::ifstream
#include <iostream> // std::cout, std::cerr, std::ostream, std::istream
using namespace std;
struct Customer {
string first_name, last_name;
int years;
float amount, interest_rate, amount_per_month;
};
// define a stream extraction operator that takes a Customer on the right hand side
// usage examples: std::cin >> customer;
// file >> customer;
istream& operator>>(istream &is, Customer &customer)
{
// don't write directly into the members of Customer to not leave
// the object in a flunky state if extraction fails for some value.
string first_name, last_name;
int years;
float amount, interest_rate, amount_per_month;
if (!(is >> first_name >> last_name >> years >> amount >> interest_rate >> amount_per_month))
return is; // if extraction of a value fails end here
// if we reach here all values have been read successfully and can be
// assigned to the customer:
customer = { first_name, last_name, years, amount, interest_rate, amount_per_month };
return is;
}
// define a stream insertion operator that takes a Customer on the right hand side
// usage examples: std::cout << customer;
// file << customer;
ostream& operator<<(ostream &os, Customer const &customer)
{
os << customer.first_name << ' ' << customer.last_name << '\n' << customer.years << ' '
<< customer.amount << ' ' << customer.interest_rate << ' ' << customer.amount_per_month;
return os;
}
int main()
{
cout << "Enter filename: ";
string fileName;
cin >> fileName;
ifstream inFile{ fileName }; // define variables as close to where they're
// used. Use the constructor where app-
// ropriate - here to open the file.
if (!inFile.is_open()) { // if the file couldn't be opened
cerr << "Unable to open \"" << fileName << "\" for reading!\n\n";
return EXIT_FAILURE; // exit main() returning a value that
} // indicates an error
cout << "Reading file \"" + fileName + "\":\n";
size_t numCustomers;
if (!(inFile >> numCustomers)) { // read the number of customers before-
// hand since this value is not part of
// a customer record.
cerr << "Couldn't read number of customers from \"" << fileName << "\"!\n\n";
return EXIT_FAILURE;
}
// use an istream_iterator that will use our stream extraction operator
// to read customers from inFile until it reaches EOF or an error occurs.
vector<Customer> Customers{ istream_iterator<Customer>{ inFile },
istream_iterator<Customer>{} };
if (numCustomers != Customers.size()) { // check if the number of customers
// specified in the file matches
// the number of customers we
// were able to extract.
cerr << "Number of customers specified in \"" << fileName
<< "\" does not match the number of customers read!\n\n";
return EXIT_FAILURE; // if the numbers don't match there was an error
} // while reading the records from the file
for (auto const &c : Customers) // just to check print the customers
std::cout << c << '\n';
}
Output:
Enter File Name: test.txt
Reading file "test.txt":
Salman Khan
20 100000 4.75 1000
Aamir khan
30 200000 5.25 1000
I have the following structure:
struct productInfo
{
int item;
string details;
double cost;
};
I have a file that will input 10 different products that each contain an item, details, and cost. I have tried to input it using inFile.getline but it just doesn't work. Can anyone give me an example of how to do this? I would appreciate it.
Edit
The file contains 10 lines that look like this:
570314,SanDisk Sansa Clip 8 GB MP3 Player Black,55.99
Can you provide an example please.
Edit
Sorry guys, I am new to C++ and I don't really understand the suggestions. This is what I have tried.
void readFile(ifstream & inFile, productInfo products[])
{
inFile.ignore(LINE_LEN,'\n'); // The first line is not needed
for (int index = 0; index < 10; index++)
{
inFile.getline(products[index].item,SIZE,DELIMETER);
inFile.getline(products[index].details,SIZE,DELIMETER);
inFile.getline(products[index].cost,SIZE,DELIMETER);
}
}
This is another approach that uses fstream to read the file and getline() to read each line on the file. The parsing of the line itself was left out on purpose since other posts have already done that.
After each line is read and parsed into a productInfo, the application stores it on a vector, so all products could be accessed in memory.
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <string>
using namespace std;
struct productInfo
{
int item;
string details;
double cost;
};
int main()
{
vector<productInfo> product_list;
ifstream InFile("list.txt");
if (!InFile)
{
cerr << "Couldn´t open input file" << endl;
return -1;
}
string line;
while (getline(InFile, line))
{ // from here on, check the post: How to parse complex string with C++ ?
// https://stackoverflow.com/questions/2073054/how-to-parse-complex-string-with-c
// to know how to break the string using comma ',' as a token
cout << line << endl;
// productInfo new_product;
// new_product.item =
// new_product.details =
// new_product.cost =
// product_list.push_back(new_product);
}
// Loop the list printing each item
// for (int i = 0; i < product_list.size(); i++)
// cout << "Item #" << i << " number:" << product_list[i].item <<
// " details:" << product_list[i].details <<
// " cost:" << product_list[i].cost << endl;
}
EDIT: I decided to take a shot at parsing the line and wrote the code below. Some C++ folks might not like the strtok() method of handling things but there it is.
string line;
while (getline(InFile, line))
{
if (line.empty())
break;
//cout << "***** Parsing: " << line << " *****" << endl;
productInfo new_product;
// My favorite parsing method: strtok()
char *tmp = strtok(const_cast<char*>(line.c_str()), ",");
stringstream ss_item(tmp);
ss_item >> new_product.item;
//cout << "item: " << tmp << endl;
//cout << "item: " << new_product.item << endl;
tmp = strtok(NULL, ",");
new_product.details += tmp;
//cout << "details: " << tmp << endl;
//cout << "details: " << new_product.details << endl;
tmp = strtok(NULL, " ");
stringstream ss_cost(tmp);
ss_cost >> new_product.cost;
//cout << "cost: " << tmp << endl;
//cout << "cost: " << new_product.cost << endl;
product_list.push_back(new_product);
}
It depends on what's in the file? If it's text, you can use the redirect operator on a file input stream:
int i;
infile >> i;
If it's binary, you can just read it in to &your_struct.
You have to
0) Create a new instance of productInfo, pinfo;
1) read text (using getline) to the first comma (','), convert this string to an int, and put it into pinfo.item.
2) read text to the next comma and put it into pinfo.details;
3) read text to the endline, convert the string to a double, and put it into pinfo.cost.
Then just keep doing this until you reach the end of the file.
Here is how I would use getline. Note that I use it once to read from the input file, and then again to chop that line at ",".
ostream& operator>>(istream& is, productInfo& pi)
{
string line;
getline(is, line); // fetch one line of input
stringstream sline(line);
string item;
getline(sline, item, ',');
stringstream(item) >> pi.item; // convert string to int
getline(sline, item, ',');
pi.details = item; // string: no conversion necessary
getline(sline, item);
stringstream(item) >> pi.cost; // convert string to double
return is;
}
// usage:
// productInfo pi; ifstream inFile ("inputfile.txt"); inFile >> pi;
N.b.: This program is buggy if the input is
99999,"The Best Knife, Ever!",16.95