Having trouble loading from a text file C++ - c++

I'm having trouble loading from a text file to a value. I want it to load from the text file, but the number remains unchanged.
Data.txt
7
7
Line 1 of the file is Health, what I'm trying to load.
Player.h
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
public:
int Health;
int MaxHealth;
Player() { this->Health = 9; this->MaxHealth = 9; }
};
#endif // PLAYER_H
and main.cpp
#include <iostream>
#include "Player.h"
#include <fstream>
using namespace std;
void save_to_file(string filename, Player P)
{
ofstream f( filename.c_str() );
f << P.Health << endl;
f << P.MaxHealth << endl;
}
bool load_from_file(string filename, Player P)
{
ifstream f( filename.c_str() );
f >> P.Health;
f >> P.MaxHealth;
return f.good();
}
int main()
{
Player P;
load_from_file("Data.txt", P);
cout << P.Health << endl;
return 0;
}
Thanks! I just learned C++ so I'm a little confused. I'm running Codeblocks and 'Data.txt' is in the 'bin' folder.
EDIT :
Changed main.
bool load_from_file(string filename, Player& P)
{
ifstream f( filename.c_str() );
f >> P.Health;
f >> P.MaxHealth;
if(f.good()){
cout << "Sucess!" << endl;
} else {
cout << "Failure" << endl;
}
return f.good();
}

Not sure what you're doing wrong if you followed πάντα ῥεῖ's advice, but this works:
#include <iostream>
#include <fstream>
using namespace std;
class Player {
public:
int Health, MaxHealth;
};
void save_to_file(string filename, const Player& P)
{
ofstream f( filename.c_str() );
f << P.Health << endl;
f << P.MaxHealth << endl;
}
bool load_from_file(string filename, Player& P) {
ifstream f( filename.c_str() );
f >> P.Health;
f >> P.MaxHealth;
if(f.good()){
cout << "Success!" << endl;
}
else {
cout << "Failure" << endl;
}
return f.good();
}
int main() {
Player P;
load_from_file("Data.txt", P);
cout << P.Health << endl;
return 0;
}

Change your function signature to take the parameter by reference:
bool load_from_file(string filename, Player& P) {
// ^
As is, your function only modifies a copy of the Player parameter, and the result isn't seen in main().

Related

How to make lambda for this function?

I am wondering how to make a lambda in C++ for this function and the type has to be void
void setIO(string s){
freopen((s+".in").c_str(),"r",stdin);
freopen((s+".out").c_str(),"w",stdout);
}
You can specify the type like so:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
const string FILE_NAME = "test.txt";
auto f = [](string const &name) -> void {
ofstream file;
file.open(name);
file << "junk\n" << "junk2" << endl;;
file.close();
};
f(FILE_NAME);
ifstream inputFile(FILE_NAME);
if (inputFile.is_open()) {
cout << "File is open." << endl;
string line;
while (getline(inputFile, line))
cout << line << '\n';
cout << flush;
inputFile.close();
} else
cerr << "Error opening file." << endl;
return EXIT_SUCCESS;
}
However, lambda functions can deduce the return type, so you can leave out -> void.
auto f = [](string const &name) {
ofstream file;
file.open(name);
file << "junk\n" << "junk2" << endl;;
file.close();
};
The equivalent way to create a lambda would be:
auto f = [](string s) -> void {
//freopen((s+".in").c_str(),"r",stdin);
//freopen((s+".out").c_str(),"w",stdout);
std::cout<<"inside lambda"<<std::endl;
//some other code here
};
Now you can use/call this as:
f("passing some string");

Create binray file in constructor

I write a small Store that contain Item. I create two function one to print content of file one to sort the records and insert them back into file. With the initializer list it display correctly the content of file, but said that there is "Error with file". How to correct this issue and what is the best way to create a binary file in constructor
#pragma once
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Item
{
char name[20];
int code;
float price;
int quantity;
Item() { code = 0, price = 0, quantity = 0;
char name1[20] = { 0 }; strcpy_s(name, 20, name1);
}
Item(const char* name, int code, float price, int quantity)
{
strcpy_s(this->name, strlen(name) + 1, name);
this->code = code;
this->price = price;
this->quantity = quantity;
}
friend ostream& operator<<(ostream& os, Item& item)
{
os << "Name: " << item.name << endl;
os << "code: " << item.code << endl;
os << "price: " << item.price << endl;
os << "quantity: " << item.quantity << endl << endl;
return os;
}
bool operator!()
{
return code != 0;
}
};
class Store
{
private:
int size = 100;
fstream file;
string fileName;
public:
Store(string fname);
~Store();
Store& operator+=(Item& myItem);
friend ostream& operator<<(ostream&, Store&);
void sortStore();
};
#include "Store.h"
Store::Store(string fname) : file(fname,ios::binary)
{
Item tmp;
if (!file)
cout << "Error with file" << endl;
for (int i = 0; i < size; i++)
file.write((char*)&tmp, sizeof(Item));
//file.close();
file.open(fname, ios::binary | ios::in | ios::out);
}
Store::~Store()
{
file.close();
}
Store& Store::operator+=(Item& myItem)
{
file.write((char*)&myItem, sizeof(myItem));
return (*this);
}
ostream& operator<<(ostream& out, Store& store)
{
Item tmp;
store.file.seekg(0, ios::beg);
for (int i = 0; i < store.size; i++)
{
store.file.read((char*)&tmp, sizeof(Item));
if (!tmp)
cout << i << ": " << tmp;
}
return out;
}
void Store::sortStore()
{
Item tmp;
vector<Item> items;
file.seekg(0, ios::beg);
while (!file.eof())
{
file.read((char*)&tmp, sizeof(Item));
items.push_back(tmp);
}
sort(items.begin(), items.end(), [](Item& first, Item& second)
{
return first.code < second.code;
});
file.clear();
remove("store.dat");
Store("store.dat");
file.seekp(0, ios::beg);
for (auto it = items.begin(); it < items.end(); it++)
file.write((char*)&(*it), sizeof(Item));
}
int main()
{
Store ourStore("store.dat");
Item apple("apple", 45, 12.2, 10);
Item ananas("ananas", 12, 27, 10);
Item strawberry("strawberry", 1, 24.2, 5);
Item banana("banana",23,14.2, 12);
ourStore.operator+=(apple);
ourStore.operator+=(ananas);
ourStore.operator+=(strawberry);
ourStore.operator+=(banana);
int choice = -1;
while (choice != 0)
{
cout << "1.Sorting, 2 Print" << endl;
switch (choice)
{
case 1:
cout << "Sorting" << endl;
ourStore.sortStore();
case 2:
cout << "Print" << endl;
cout << ourStore << endl;
}
cin >> choice;
}
return 0;
}
The local variable file in Store::Store hides the member variable Store::file.
You want an initializer list:
Store::Store : file(fname, ios::binary)
{
// ...

Visual Studio 2015 C2011 'Class' type redefinition

im currently working on a small console app, i read from some files, and i have made a simple animated loading bar thread to show the progress of file reading (sometimes the file are really huge)
i have read on the microsoft documentation and on the forum and that error seems to suggest that i defined the class multiple time.
but i did include all the header blocks to prevent this from happenning, any of you see my mistake, probly obvious, i havent done c++ in years.
here is the code
fileReader.h
#pragma once
#ifndef FILEREADER_H // must be unique name in the project
#define FILEREADER_H
#include <vector>
using namespace std;
class fileReader {
private:
public:
vector<string> readTextFile(string path);
unsigned int getSize();
unsigned int getLoadedBytes();
};
#endif // FILEREADER_H
#pragma once
fileReader.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <thread>
#include "numbers.h"
#include "loadingBar.h"
using namespace std;
class fileReader {
private:
public :
vector<string> list;
int i;
unsigned int size;
unsigned int loadedBytes;
string line;
std::thread* barThread;
vector<string> fileReader::readTextFile(string path) {
ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
i = 0;
size = 0;
loadedBytes = 0;
ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
if (file.is_open()) {
size = file.tellg();
cout << "\t" << path << " (" << formatNumbers(size) << " bytes)" << endl;
file.clear();
file.seekg(0, ios::beg);
barThread = new std::thread(&loadingBar::run, *this);
while (file >> line) {
list.push_back(line);
loadedBytes += strlen(line.c_str());
i++;
}
}
else {
cout << "Error reading : \"" << path << "\"" << endl;
exit(EXIT_FAILURE);
}
file.close();
return list;
}
unsigned int fileReader::getSize() { return size; }
unsigned int fileReader::getLoadedBytes() { return loadedBytes; }
};
loadingBar.h
#pragma once
#ifndef LOADINGBAR_H
#define LOADINGBAR_H
#include<stdlib.h>
#include<string>
#include<iomanip>
#include "numbers.h"
#include "fileReader.h"
using namespace std;
class loadingBar {
public:
void notififyFinish();
void notifyError();
void notifiError(string);
void drawloadingBar();
void drawPathBar();
void drawBytesBar();
void setLoadedUnits(int);
void setTotalUnits(int);
void run(fileReader*);
};
#endif // NUMBERS_H
loadingBar.cpp
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include "numbers.h"
#include "fileReader.h"
using namespace std;
class loadingBar {
private:
public:
double totalUnits = 1;
double loadedUnits = 0;
char loadedChar = '/';
char emptyChar = ' ';
int barLength = 50;
double percent;
int nbChar;
void notiftyFinish() {
cout << " Ok" << endl;
//exit(EXIT_SUCCESS);
}
void notifiyError() {
cout << " Error !" << endl;
//exit(EXIT_FAILURE);
}
void notifiyError(string errMess) {
cout << " Error !" << endl << "\t" << errMess;
//exit(EXIT_FAILURE);
}
void drawLoadingBar() {
cout << fixed;
cout << "\rLoading [";
for (int i = 0; i < nbChar; i++)
cout << loadedChar;
for (int i = nbChar; i < barLength - 1; i++)
cout << emptyChar;
cout << "] " << setprecision(0) << percent << "%";
}
void drawPathBar(string path) {
cout << fixed;
cout << "\rLoading [ ";
cout << path;
cout << " ] " << setprecision(0) << percent << "%";
}
void drawBytesBar() {
cout << fixed;
cout << "\rLoading [ ";
cout << formatNumbers(loadedUnits) << " / " << formatNumbers(totalUnits);
cout << " ] " << setprecision(0) << percent << "%";
}
void setLoadedUnits(int newValue) {
if (newValue > 0)
loadedUnits = newValue;
}
void setTotalUnits(int value) {
if (value > 0)
totalUnits = value;
}
void run(fileReader *f) {
setTotalUnits(f->getSize());
setLoadedUnits(f->getLoadedBytes());
while (loadedUnits <= totalUnits) {
setLoadedUnits(f->getLoadedBytes());
percent = ((double)(loadedUnits / totalUnits) * 100);
nbChar = (int)(percent / (int)(100 / barLength));
drawLoadingBar();
//setLoadedUnits((int)loadedUnits + 10);
if (loadedUnits >= totalUnits) notiftyFinish();
}
}
};
Your .cpp files redefine your classes. You've already defined them in the respective .h files. All you need to include in your .cpp files is the implementations. They should look more like this:
fileReader.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <thread>
#include "numbers.h"
#include "loadingBar.h"
vector<string> fileReader::readTextFile(string path) {
ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
i = 0;
size = 0;
loadedBytes = 0;
ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
if (file.is_open()) {
size = file.tellg();
cout << "\t" << path << " (" << formatNumbers(size) << " bytes)" << endl;
file.clear();
file.seekg(0, ios::beg);
barThread = new std::thread(&loadingBar::run, *this);
while (file >> line) {
list.push_back(line);
loadedBytes += strlen(line.c_str());
i++;
}
}
else {
cout << "Error reading : \"" << path << "\"" << endl;
exit(EXIT_FAILURE);
}
file.close();
return list;
}
unsigned int fileReader::getSize() { return size; }
unsigned int fileReader::getLoadedBytes() { return loadedBytes; }
Similarly for loadingBar.cpp.

How to read data from a text file into a struct

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";
}
}

C++ read/write to binary file. on program exit it gives System.AccessViolationException

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.