I have made a book storage program in c++. It is program which loops over 3 times so the user can input 3 books but now I want user to pick the amount of book user wants to enter and I have no clue how to do it. It would be helpful and here is my code
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct Book{
string name;
int release;
}Issue[3];
int main(){
//local variable
int i;
string release_dte;
//interface
cout << "Welcome to Book Storage CPP" << endl;
//for handler
for (i = 0; i < 3; i++){
cout << "Book: ";
getline(cin, Issue[i].name);
cout << "Release Date: ";
getline(cin, release_dte);
Issue[i].release = atoi(release_dte.c);
}
cout << "These are your books" << endl;
for ( i = 0; i < 3; i++){
cout << "Book: " << Issue[i].name << " Release Date: " << Issue[i].release << endl;
}
system("pause");
return 0;
}
The best way is to use std::vector. For example
#include <vector>
//...
struct Book{
string name;
int release;
};
int main()
{
size_t issue_number;
std::cout << "Enter number of books: ";
std::cin >> issue_number;
std::vector<Book> Issue( issue_number );
//...
Otherwise you should dynamically allocate the array yourself. For example
Book *Issue = new Book[issue_number];
and in the end of the program you need to release the allocated memory
delete []Issue;
Extending (and critiquing) Vlad's answer, you won't need the amount of the books beforehand if you utilize stream iterators. You can also overload the stream extractor for Book so that the extraction is correctly implemented by the iterators:
std::istream& operator>>(std::istream& is, Book & b)
{
if (!is.good())
return is;
std::string release_date;
if (std::getline(is >> std::ws, b.name) &&
std::getline(is >> std::ws, release_date))
{
b.release = std::stoi(release_date);
}
return is;
}
And later in main() you would still use std::vector<Book>, only using the iterator overload of the constructor to generate the objects:
int main()
{
std::vector<Book> Items(std::istream_iterator<Book>{std::cin},
std::istream_iterator<Book>{});
...
}
For printing you can overload the inserter which implements the logic for printing:
std::ostream& operator<<(std::ostream& os, const Book & b)
{
return os << "Book: " << b.name << '\n'
<< " Release Date: " << b.release;
}
And invoking this inserter using std::copy:
std::copy(Items.begin(), Items.end(),
std::ostream_iterator<Book>(std::cout << "These are your books: \n", "\n"));
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Book {
string name;
int release;
Book(string _name, int _release) {
name = _name;
release = _release;
}
};
int main() {
vector<Book> books;
string name;
int release;
while(cin >> name >> release) {
books.push_back(Book(name,release));
}
for(int i=0; i<(int)books.size(); ++i) {
cout << books[i].name << " - " << books[i].release << endl;
}
return 0;
}
Related
I am trying this piece of code in vs 2008
#include <stdio.h>
#include <iostream>
#include <string>
typedef struct _first
{
int age;
std::string name;
}first;
typedef struct _second
{
int age;
char name[20];
}second;
void copy_structure()
{
first s;
second f;
f.age = 15;
cout<<"Enter the name"<<endl;
fgets(f.name, 20, stdin);
memcpy(&s,&f,20);
cout << "Name: " << s.name << endl;
cout << "Age: "<< s.age << endl;
}
int main()
{
copy_structure();
return 0;
}
while building I didn't get any error but when I run, name field is empty over here
cout << "Name: " << s.name << endl;
I am not getting any output over here, can somebody help me to solve this issue.
You should use an approach based on member-wise copying. For example
void copy_structure()
{
first f;
^^
second s;
^^
s.age = 15;
cout<<"Enter the name"<<endl;
fgets(s.name, 20, stdin);
f.age = s.age;
f.name = s.name;
cout << "Name: " << f.name << endl;
cout << "Age: "<< f.age << endl;
}
Otherwise the internals of the object name of the type std::string will be overwritten and the program will have undefined behaviour.
This looks like C but not like C++... Your current code will also brick your std::string instance. memcpy is dangerous and should not be used, unless you have a very, very good reason. I never had a reason for this so far.
My suggestion:
#include <iostream>
#include <string>
using namespace std;
struct second
{
int age;
char name[20];
};
struct first
{
int age;
string name;
first& operator=(const second& rhs);
};
// some operator for copying
first& first::operator=(const second& rhs)
{
age = rhs.age;
name = rhs.name;
return *this;
}
int main()
{
first s;
second f;
f.age = 15;
cout << "Enter your name" << endl;
cin >> f.name;
s = f;
cout << "Name: " << s.name << endl;
cout << "Age: " << s.age << endl;
return 0;
}
This is improvable, of course. You would usually rather use classes than structs. And you would might also have an operator>> for second.
I'm completely new to C++ and currently I'm trying to read very basic text file which look like this:
Dr John Doe
British
2
Soccer
Swimming
and my expected output should look like:
My information
Name: John Doe
Nationality: British
I have 2 hobbies:
1. Soccer
2. Swimming
My header file:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;
const int MAX = 80;
const int MAXNO = 5;
enum Title {Miss, Mrs, Mr, Dr, Unknown};
struct Date
{
int day;
int month;
int year;
};
struct MyInfo
{
char name [MAX];
char national [MAX];
int noOfHobbies;
char hobby [MAXNO][MAX];
};
void getMyInfo (fstream& , char[] , MyInfo&);
void displayMyInfo (MyInfo);
My functions:
#include "Lab_1.h"
void getMyInfo (fstream& afile,char fileName[], MyInfo& x) {
afile.open (fileName);
if (!afile)
{
cout << "Binary file " << fileName << " opened for creation failed" << endl;
exit (-1);
}
cout << "\n" << "Begin reading of " << fileName << endl;
string line;
while(getline(afile, line))
{
afile >> x.national;
afile >> x.noOfHobbies;*/
if (afile >> x.name >> x.national >> x.noOfHobbies) {
cout << "Name: " << x.name << ", "
<< "National: " << x.national << ", "
<< "noOfHobbies: " << x.noOfHobbies << ", "
<< endl;
}
}
}
void displayMyInfo (MyInfo x) {
}
My main function:
#include "Lab_1.h"
int main () {
fstream afile;
MyInfo x;
string fileName;
getMyInfo(afile,"textfile.txt",x);
//displayMyInfo(x);
afile.close ();
}
The above code output nothing because I just put everything I understand over the forum with similar question. Since I'm already stuck for 1 day even though I've already done a lot of research but most of them suggest to use vector which I'm not familiar with at this moment, so can someone give me a solution to this problem? Thank you very much for your help in advance.
Random act of madness kindness:
Live On Coliru
#include <fstream>
#include <set>
struct Person {
std::string name;
std::string nationality;
std::set<std::string> hobbies;
friend std::istream& operator>>(std::istream& is, Person& into) {
size_t n = 0;
if (getline(is, into.name) &&
getline(is, into.nationality) &&
is >> n && is.ignore(1024, '\n'))
{
while (n--) {
std::string hobby;
if (getline(is, hobby))
into.hobbies.insert(hobby);
else
is.setstate(std::ios::failbit);
}
}
return is;
}
};
#include <iostream>
int main() {
std::ifstream ifs("input.txt");
Person p;
if (ifs >> p) {
std::cout << "My information\n";
std::cout << p.name << "\n";
std::cout << p.nationality << "\n";
std::cout << "I have " << p.hobbies.size() << " hobbies:\n";
size_t counter = 0;
for(auto const& hobby : p.hobbies) {
std::cout << ++counter << ". " << hobby << "\n";
}
} else {
std::cerr << "Parse failure\n";
}
}
How to get program read every line from .txt file and store 3 variables per line in different place ? I don't understand how can I store different value in same class. One line works fine but what I have tried more doesn't work.
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(Team& ko);
int main()
{
Team ko;
GetTeamInfo(ko);
cout << ko.name << " ";
cout << ko.dificulty<< " ";
cout << ko.section<< " ";
system("PAUSE");
}
void GetTeamInfo(Team& ko, int & i)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
for(int i = 0; i < 10 ; i ++)
{
fd >> ko.name;
fd >> ko.dificulty;
fd >> ko.section ;
}
}
else
{
std::cout << "Mistake can't open file 'Team.txt'\n";
}
}
Try this:
void GetTeamInfo(vector<Team>& kos)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
while (!d.eof())
{
Team ko;
fd >> ko.name;
fd >> ko.dificulty;
fd >> ko.section;
kos.push_back(ko);
}
}
...
}
I suggest you use a std::vector, since you have a number of teams.
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
using namespace std;
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(vector<Team>& ko_v);
int main()
{
vector<Team> ko; // a vector of Teams
GetTeamInfo(ko); // read from file inside a vector
// print every team
for(unsigned int i = 0; i < ko.size(); ++i) {
cout << ko[i].name << " ";
cout << ko[i].dificulty<< " ";
cout << ko[i].section<< " ";
cout << "\n";
}
//system("PAUSE"); // don't use system()
return 0; // return 0 should be placed at the end of main
}
void GetTeamInfo(vector<Team>& ko_v) // you had an extra parameter here, no need to
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open()) // check if file is open
{
while (!fd.eof()) // while you have more to read
{
Team ko; // create a Team
fd >> ko.name; // read data
fd >> ko.dificulty;
fd >> ko.section;
ko_v.push_back(ko); // store that Team in the vector of teams
}
}
else
{
cout << "File not opened!\n";
}
}
Why not to use an array? You could use an array of course, but since this is C++, std::vector's usage is encouraged. Moreover, you don't have to worry about the number of the Teams you are going to read from the file. If you would have used an array, you should know apriori the number of the Teams, or dynamically allocate memory.
Why not use system(pause); ?
Just for a glance, I am modifying the example with the use of an array.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Team
{
public:
string name;
string dificulty;
string section;
};
void GetTeamInfo(Team* ko_ar, const int N);
int main()
{
const int N = 3; // number of teams in the file
Team ko[N]; // a vector of Teams
GetTeamInfo(ko, N); // read from file inside a vector
// print every team
for(int i = 0; i < N; ++i) {
cout << ko[i].name << " ";
cout << ko[i].dificulty<< " ";
cout << ko[i].section<< " ";
cout << "\n";
}
//system("PAUSE"); // don't use system()
return 0; // return 0 should be placed at the end of main
}
void GetTeamInfo(Team* ko_ar, const int N)
{
ifstream fd;
fd.open("Team.txt");
int i = 0;
if (fd.is_open()) // check if file is open
{
while (!fd.eof()) // while you have more to read
{
Team ko; // create a Team
fd >> ko.name; // read data
fd >> ko.dificulty;
fd >> ko.section;
if(i == N) {
cout << "Read more than " << N << " teams\n";
break;
}
ko_ar[i++] = ko; // store that Team in the vector of teams
}
}
else
{
cout << "File not opened!\n";
}
cout << "Read " << i << " teams\n";
}
Use a vector, here you have a full example(commented):
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Team
{
public:
// Adding a constructor.
Team(string name, string dificulty, string section):
name(name),
dificulty(dificulty),
section(section)
{}
string name;
string dificulty;
string section;
};
// Defining a convenience type;
typedef vector<Team> team_list_t;
// This function now receives a vector of teams.
void GetTeamInfo(team_list_t &tl);
int main()
{
team_list_t tl;
GetTeamInfo(tl);
for (vector<Team>::iterator it = tl.begin(); it != tl.end(); ++it)
cout << it->name << " " << it->dificulty << " " << it->section << endl;
// You can also ...
for (int i = 0; i < tl.size(); i++)
cout << tl[i].name << " " << tl[i].dificulty << " " << tl[i].section << endl;
}
void GetTeamInfo(team_list_t& tl)
{
ifstream fd;
fd.open("Team.txt");
if (fd.is_open())
{
// Define variables;
string name, dificulty, section;
// Read until EOF
while(fd >> name >> dificulty >> section)
{
// Add teams to the vector/list.
tl.push_back(Team(name, dificulty, section));
}
}
else
{
std::cout << "Mistake can't open file 'Team.txt'\n";
}
}
So, the problem is several errors at compile time.
ReadMovieData(string* title, string* director) cannot convert from movieInfo to string*
DisplayMovieData(string title, string director) cannot convert from movieInfo to string
No operator found which takes a right-hand operand of type 'movieInfo' (or there is no acceptable conversion.
The bottom error happens twice in DisplayMovieData() so I wrote it once for simplicity sake.
The ReadMovieData function should accept a structure pointer reference variable and the DisplayMovieData function should accept a MovieInfo structure variable.
The main function creates an array of 2 MovieInfo struct variables and the other functions should be called on an element of the array.
The code I have finished is below.
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
//prototypes
int ReadMovieData(string* title, string* director);
int DisplayMovieData(string title, string director);
struct movieInfo {
string title, director;
};
int main(){
const int SIZE = 2;
movieInfo movieList[SIZE];
movieInfo movie;
//supposed to assign data to movieList[i] at some point
for (int i = 0; i < SIZE; i++){
ReadMovieData(movie, movie);
DisplayMovieData(movie, movie);
}
return 0;
}
int ReadMovieData(movieInfo &title, movieInfo &director){
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return 0;
}
int DisplayMovieData(movieInfo title, movieInfo director){
cout << "The movie name is: " << title << endl;
cout << "The director of " << title << " is: " << director << endl;
return 0;
}
There are mismatches between your function prototypes and their definitions, as you can see comparing the parameter types in both.
Note that since you defined a structure for the movie info, you can directly pass it to the reading and displaying functions (instead of passing the single structure data member strings).
You may want to read the following compilable code:
#include <iostream>
#include <string>
using namespace std;
struct MovieInfo {
string title;
string director;
};
void ReadMovieData(MovieInfo& movie);
void DisplayMovieData(const MovieInfo& movie);
int main() {
const int SIZE = 2;
MovieInfo movieList[SIZE];
for (int i = 0; i < SIZE; i++) {
ReadMovieData(movieList[i]);
DisplayMovieData(movieList[i]);
}
}
// Since movie is an output parameter in this case, pass by non-const reference.
void ReadMovieData(MovieInfo& movie) {
//get the movie name
cout << "What is the movie? ";
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin >> movie.director;
}
// Since movie is an input parameter in this case, pass by reference to const.
void DisplayMovieData(const MovieInfo& movie) {
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title
<< " is: " << movie.director << endl;
}
The errors are pretty explanatory and clear - your function takes string* but you're passing movieInfo - unrelated types can't just magicaly convert one to another.
What you probably want is pass the data members of movieInfo:
ReadMovieData(&movie.title, &movie.director);
It would be better if arguments were not pointers - use references instead. Where you won't be changing the arguments, the references should be to const type.
Even better, why not just pass moveInfo
ReadMovieData(movieInfo& movie);
and let the function deal with the internals of the class? This better encapsulates data and doesn't lead to spaghetti code quite so fast.
Also, the declarations and definitions need to match (otherwise you'd be overloading) - you're using pointers in some places and references/values in others.
Finally, here's how an overload of operator<< might look like:
std::ostream& operator<<(std::ostream& os, const movieInfo& m)
{
return os << "Title: " << m.title << ", Director: " << m.director;
}
Your class movieInfo does not have an overloaded << operator, which is necessary is you want to work with iostream, however, you can pass the strings contained in movieInfo:
int DisplayMovieData(string &title, string &director) { }
Call like:
DisplayMovieData(movie.title, movie.director);
You are declaring the function with this signature
int ReadMovieData(string* title, string* director);
but you're defining it using
int ReadMovieData(movieInfo &title, movieInfo &director) {
// ...
}
These don't match!
The code is totally invalid. I suppose the valid code should look the following way
#include <stdafx.h>
#include <string>
#include <iomanip>
#include <iostream>
using namespace std;
struct movieInfo
{
string title, director;
};
//prototypes
movieInfo ReadMovieData();
void DisplayMovieData( const movieInfo & );
int main()
{
const int SIZE = 2;
movieInfo movieList[SIZE];
//supposed to assign data to movieList[i] at some point
for ( int i = 0; i < SIZE; i++ )
{
movieList[i] = ReadMovieData();
DisplayMovieData( movieList[i] );
}
return 0;
}
movieInfo ReadMovieData()
{
movieInfo movie;
//get the movie name
cout << "What is the movie? ";
cin.ignore();
cin >> movie.title;
//get the movie director
cout << "What is the director of " << movie.title << "?";
cin.ignore();
cin >> movie.director;
return movie;
}
void DisplayMovieData( const movieInfo &movie )
{
cout << "The movie name is: " << movie.title << endl;
cout << "The director of " << movie.title << " is: " << movie.director << endl;
}
This C++ program is created using Visual Studio 2010. It's a group project that has everyone in class stumped.
The program initially starts fine and the user can run through the program and add items that are written out to file. the items are read back in and displayed. When the user is done, on the program exiting return 0; it gives me "An unhandled exception of type System.AccessViolationException occurred. Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
When this happens it opens up a file called utility here => for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter; *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter) (*_Pnext)->_Myproxy = 0.
I can fix this by replacing return 0; with exit(0);
I know it's not a real fix though and just a band-aid over a bullet hole that is causing this issue.
After fixing (used very loosely here) that, then running the program again, it attempts to load the data file from the file system. It reads and loads the 1st item into a vector correctly but when it goes back to the start of the loop we see the same exception pop up, An unhandled exception of type System.AccessViolationException occurred.
This is the first project we have worked on using fstream and binary i/o. We had worked through a similar program that was just reading and writing strings w/out any issues.I believe that the issue stems from something in the fileHandler class but am having a difficult time pinpointing what is causing this issue.Any advice/help is greatly appreciated.Here is the code.stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <string>
#include <vector>
#include <time.h>
Week2.cpp (the main file for the project)
//Week2.cpp *******************
#include "stdafx.h"
#include "fileHandler.h"
using namespace std;
using namespace System;
int main(array<System::String ^> ^args)
{
fileHandler theFile("store.pkl");
vector<item> itemStack = theFile.getFile();
cout << "SKU Name Dept Vendor Max Order onHand" << endl;
cout << "-------------------------------------------" << endl;
for (int i = 0; i < itemStack.size(); i++)
{
cout << itemStack[i].toString() << endl;
}
vector<item> newStack;
//prompt for input
bool doneEditing = false;
while(!doneEditing)
{
int A;
int E;
int F;
int G;
string B;
string C;
string D;
string tempString;
cout << "Enter item info:" << endl << "Item SKU: ";
cin >> A;
cout << endl << "Item Name: ";
cin >> B;
cout << endl << "Item Dept: ";
cin >> C;
cout << endl << "Vendor Name: ";
cin >> D;
cout << endl << "Max Number: ";
cin >> E;
cout << endl << "Reorder Number: ";
cin >> F;
cout << endl << "OnHand Number: ";
cin >> G;
cout << endl << "Done?? Y/N: ";
cin >> tempString;
cout << endl;
item tempItem = item(A, B, C, D, E, F, G);
newStack.push_back(tempItem);
if (tempString == "Y" || tempString == "y")
{
doneEditing = true;
}
}
cout << "Saving stack to file" << endl;
theFile.putFile(newStack);
cout << "Items written to file" << endl;
vector<item> newFileStack = theFile.getFile();
cout << "After reload: " << endl;
cout << "SKU Name Dept Vendor Max Order onHand" << endl;
cout << "-------------------------------------------" << endl;
for (int i = 0; i < newFileStack.size(); i++)
{
cout << newFileStack[i].toString() << endl;
}
cout << "Thank you for using the Awesome Grocery Inventory Application" << endl;
system("PAUSE");
/*return 0; this breaks with same error as
when reading in saved file after application restart
*/
exit(0);
}
item.h
using namespace std;
#pragma once
class item
{
public:
item();
item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand);
~item(void);
string toString();
int ItemSKU() const;
void ItemSKU(int val);
string ItemName() const;
void ItemName(string val);
string VendorName() const;
void VendorName(string val);
int MaxNumb() const;
void MaxNumb(int val);
int ReorderNumb() const;
void ReorderNumb(int val);
int OnHandNumb() const;
void OnHandNumb(int val);
private:
int itemSKU;
string itemName;
string itemDept;
string vendorName;
int maxNumb;
int reorderNumb;
int onHandNumb;
};
item.cpp
#include "StdAfx.h"
#include "item.h"
using namespace std;
item::item()
{
};
item::item(int sku, string name, string dept, string vendor, int max, int reorder, int onhand)
{
itemSKU = sku;
itemName = name;
itemDept = dept;
vendorName = vendor;
maxNumb = max;
reorderNumb = reorder;
onHandNumb = onhand;
}
item::~item(void)
{
}
string item::toString()
{
stringstream ss;
ss << itemSKU << "\t" << itemName << "\t" << itemDept << "\t" << vendorName << "\t" << maxNumb << "\t" << reorderNumb << "\t" << onHandNumb;
string s = ss.str();
return s;
}
int item::ItemSKU() const { return itemSKU; }
void item::ItemSKU(int val) { itemSKU = val; }
string item::ItemName() const { return itemName; }
void item::ItemName(string val) { itemName = val; }
string item::VendorName() const { return vendorName; }
void item::VendorName(string val) { vendorName = val; }
int item::MaxNumb() const { return maxNumb; }
void item::MaxNumb(int val) { maxNumb = val; }
int item::ReorderNumb() const { return reorderNumb; }
void item::ReorderNumb(int val) { reorderNumb = val; }
int item::OnHandNumb() const { return onHandNumb; }
void item::OnHandNumb(int val) { onHandNumb = val; }
fileHandler.h
#include "item.h"
using namespace std;
#pragma once
class fileHandler
{
public:
fileHandler(string);
~fileHandler(void);
vector<item> getFile();
void putFile(vector<item> &);
private:
string theFileName;
};
fileHandler.cpp
#include "stdafx.h"
#include "fileHandler.h"
using namespace std;
fileHandler::fileHandler(string name)
{
theFileName = name.c_str();
}
fileHandler::~fileHandler(void)
{
}
vector<item> fileHandler::getFile()
{
ifstream inFile;
string fileLine;
vector<item> localStack;
inFile.open(theFileName, ios::in|ios::binary);
if (inFile)
{
cout << "Getting file..." << endl;
cout << endl;
// not working on initial load if file is present at start
inFile.seekg(0);
while(!inFile.eof())
{
item tempItem;
inFile.read(reinterpret_cast< char * >(&tempItem), sizeof(item));
localStack.push_back(tempItem);
cout << "item added to stack" << endl;
} //breaks from here after reading in 1 item from saved file on reopen
} else {
ofstream newFile;
newFile.open(theFileName, ios::out|ios::binary);
newFile.close();
cout << "Creating new file..." << endl;
cout << endl;
inFile.open(theFileName, ios::in|ios::binary);
}
inFile.clear();
inFile.close();
if (localStack.size() > 0)
{
//removes some dirty data from end of stack
localStack.pop_back();
}
return localStack;
}
void fileHandler::putFile( vector<item> &items )
{
ofstream outFile;
outFile.open(theFileName, ios::out|ios::binary);
if(!outFile)
{
cerr<<"File could not be created"<<endl;
system("pause");
exit(1);
}
for (int i = 0; i < items.size(); i++)
{
outFile.write(reinterpret_cast<const char *>(&items[i]), sizeof(item));
}
outFile.clear();
outFile.close();
}
You cannot perform binary I/O this way with an object that contains std::string members. A std::string contains pointer(s) to dynamically allocated memory for its actual contents. You need to perform some type of serialization instead. The usual suggestion is Boost serialization.