Inserting info from a file into a struct - c++

I want to extract data from a file and store them into the myWorld but my for loop doesn't work, the program doesn't loop one time once it gets to the for loop. I'm not sure what the problem is. This is my code so far.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
struct Country
{
double pop1950;
double pop1970;
double pop1990;
double pop2010;
double pop2015;
string name;
};
const int MAXCOUNTRIES = 300;
struct World
{
int numCountries;
Country countries[MAXCOUNTRIES];
} myWorld;
void printPop ();
int main ()
{
printPop();
return 0;
}
void printPop()
{
ifstream inFile("population.csv");
if (!inFile.fail())
{
cout << "File has opened successfully.";
}
if (inFile.fail())
{
cout << "File has failed to open.";
exit(1);
}
for (int i = 0; i < MAXCOUNTRIES; i++)
{
inFile >> myWorld.countries[i].pop1950 >> myWorld.countries[i].pop1970 >> myWorld.countries[i].pop1990
>> myWorld.countries[i].pop2010 >> myWorld.countries[i].pop2015;
getline (cin, myWorld.countries[i].name);
cout << "loop is running" << endl;
}
inFile.close();
}

I think your loop is running, its just waiting for user input here :
getline (cin, myWorld.countries[i].name);

Related

Expression: Vector subscript out of range. Error 3 when using abort in console

I am unsure of what the issue is since I had no issues with my project the last time, I was working on it. I woke up this morning went to test what I had so far, and I've been hit with the "Expression: Vector subscript out of range" in an error screen right before it closes with error 3 when I click the abort button. It's a simple console RPG using C++ and I'm not sure what my vector is doing. It's involved in saving and loading characters to play the game with.
Game.h:
#pragma once
#include "Functions.h"
#include "Event.h"
#include <iostream>
#include <string>
#include <iomanip>
#include <ctime>
#include <vector>
#include <fstream>
using namespace std;
class Game
{
public:
Game();
virtual ~Game();
//Operators
//Functions
void mainMenu();
void InitGame();
void createNewCharacter();
void saveCharacter();
void loadCharacter();
void Travel();
//Accessors
inline bool getPlaying() const { return this->playing; }
//Modifiers
private:
int start;
bool playing;
//Character related
int activeCharacter;
string fileName;
vector<Character> character;
};
And these are the functions involved with the vector. in my Game.cpp
void Game::createNewCharacter() {
string name;
cout << endl;
cout << "enter name for new character: ";
getline(cin, name);
character.push_back(Character());
activeCharacter = character.size() - 1;
character[activeCharacter].Init(name);
}
void Game::saveCharacter() {
ofstream outFile(fileName);
if (outFile.is_open()) {
for (size_t i = 0; i < character.size(); i++) {
outFile << character[i].getAsString() << "\n";
}
}
outFile.close();
}
void Game::loadCharacter() {
ifstream inFile(fileName);
this->character.clear();
string name = "";
int gold = 0;
int distanceTrav = 0;
int level = 0;
int exp = 0;
int Str = 0;
int Con = 0;
int Dex = 0;
int hp = 0;
int movespeed = 0;
int statPoints = 0;
string line = "";
stringstream ss;
if (inFile.is_open()) {
while (getline(inFile, line)) {
ss.str(line);
ss >> name;
ss >> gold;
ss >> distanceTrav;
ss >> level;
ss >> exp;
ss >> Str;
ss >> Con;
ss >> Dex;
ss >> hp;
ss >> movespeed;
ss >> statPoints;
Character temp(name, gold, distanceTrav, level, Str, Con, Dex, hp, movespeed, statPoints);
this->character.push_back(Character(temp));
cout << "Character " << name << " loaded!\n";
}
}
inFile.close();
if (this->character.size() <= 0) {
throw "Error! No Characters Loaded or Empty File";
}
}
void Game::Travel() {
this->character[activeCharacter].travel();
Event ev;
ev.createEvent(this->character[activeCharacter]);
}
And this is my main:
#include "Game.h"
int main()
{
srand(time(NULL));
//int level = 12;
//int i = static_cast<int>((280 / 3) * ((pow(level, 3) - 6 * pow(level, 2)) + 17 * level - 12));
// cout << i << endl;
Game game;
game.InitGame();
Inventory inv;
//inv.addItem(Item());
//inv.debugPrint();
while (game.getPlaying()) {
game.mainMenu();
}
return 0;
}
In InitGame all I do is say welcome to the game, and the mainMenu is a case function that doesn't even get called before the error hits. If you need any more info, I will gladly provide it, I'm struggling with this probably obvious error for hours now.
In game.cpp you have
for (size_t i = 0; i < character.size(); i++) {
outFile << character[i].getAsString() << "\n";
}
shouldn't it be the activeCharacter var you created earlier.
for (size_t i = 0; i < activeCharacter; i++) {
outFile << character[i].getAsString() << "\n";
}
say character vector has 10 elements, character.size() will return to so character[10] would be the supposed 11th element(out of bounds) since its supposed to be zero indexed (hence the activeCharacter = character.size() - 1) you declared earlier.

C++, Keep Adding Records To a File besd on User confirmation

Below code is able to send a single student information to a file at once. How can it modified to send more records one after another without exiting and re-opening the program. I'm new for this. Kindly help.
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <windows.h>
#include <sstream>
#include <algorithm>
#include <conio.h>
#include <stdio.h>
#include <cstdlib>
#include <iomanip>
#include <dos.h>
using namespace std;
string userName;
string passWord;
string selection;
int option;
struct patientinfo {
string PatientFname;
string PatientLname;
int Age;
int ContactNo;
string TreatmentType;
string AppDate;
string AppTime;
int eReciptId;
};
int num;
patientinfo emp[50];
void makeBooking()
{
ofstream outputFile;
outputFile.open("smt.bin", std::ofstream::in | std::ofstream::out | std::ofstream::app);
int i=num;
num+=1;
cout<< endl << endl << endl << endl << endl << endl
<< setw(30)<<"First Name : ";
cin>>emp[i].PatientFname;
outputFile <<emp[i].PatientFname <<",";
cout<< setw(30)<<"Last Name : ";
cin>>emp[i].PatientLname;
outputFile <<emp[i].PatientLname <<",";
cout<< setw(30)<<"Age : ";
cin>>emp[i].Age;
outputFile <<emp[i].Age <<",";
}
int main ()
{
makeBooking();
return 0;
}
Considering you have 50 students to whom you want to send information you should call the makeBooking function 50 times. So changing your main in
int main ()
{
for (int i = 0; i < 50; i++) {
makeBooking();
}
return 0;
}
should do the trick.
However, a more elegant solution would be to send the index i as a parameter in your function. So the code would be:
patientinfo emp[50];
void makeBooking(int i)
{
ofstream outputFile;
outputFile.open("smt.bin", std::ofstream::in | std::ofstream::out | std::ofstream::app);
// int i=num; you don't need these anymore
// num+=1;
cout<< endl << endl << endl << endl << endl << endl
<< setw(30)<<"First Name : ";
cin>>emp[i].PatientFname;
outputFile <<emp[i].PatientFname <<",";
cout<< setw(30)<<"Last Name : ";
cin>>emp[i].PatientLname;
outputFile <<emp[i].PatientLname <<",";
cout<< setw(30)<<"Age : ";
cin>>emp[i].Age;
outputFile <<emp[i].Age <<",";
}
int main ()
{
char response;
for (int i = 0; i < 50;) {
cout << "Do you want to add another person?";
cin >> response;
if (response == 'y')
makeBooking(i++);
else if (respinse == 'n')
break;
else
cout << "Undefined response";
}
return 0;
}

c++ saving struct into a file issue

I am having an issue with my function in c++ that saves a structure to a file. It appears to save everything correctly, when I open the file back up everything has been saved. But when I run the program again the loading file goes into an infinite loop for some reason, I am uncertain as to why this is happening. Any input would be welcome.
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <fstream>
using namespace std;
struct account
{
string acctNum;
string name;
float cBal;
float sBal;
};
int menu();
char subMenu();
int loadCustomers(account[]);
void saveCusomers(account[], int);
int newCustomer(account[], int);
int deleteCustomer(account[], int);
int findCustomer(account[], int);
void deposit(account[], int);
void withdrawl(account[], int);
void balance(account[], int);
void bankBalance(account[], int);
int main()
{
account acc[20];
int selection;
int numAcc = 0;
numAcc = loadCustomers(acc);
saveCusomers(acc, numAcc);
return 0;
}
int loadCustomers(account acc[])
{
ifstream inFile;
int numCustomers = 0, i = 0;
inFile.open("customer.dat");
if (!inFile)
{
cout << "No customer file found." << endl;
}
else
{
cout << "Customer file found..." << endl << endl;
while (!inFile.eof())
{
getline(inFile, acc[i].acctNum, '#');
getline(inFile, acc[i].name, '#');
inFile >> acc[i].cBal;
inFile.ignore();
inFile >> acc[i].sBal;
i++;
numCustomers++;
}
cout << "Number of customers found in file: " << numCustomers << endl;
}
inFile.close();
return numCustomers;
}
void saveCusomers(account acc[], int numCustomers)
{
ofstream outFile;
outFile.open("customer.dat");
for (int i = 0; i < numCustomers; i++)
{
outFile << acc[i].acctNum;
outFile << '#';
outFile << acc[i].name;
outFile << '#';
outFile << acc[i].cBal;
outFile << '#';
outFile << acc[i].sBal;
outFile << '#';
}
outFile.close();
}
I am not sure if I am saving it infinitely or why it loops infinitely, any comments would help.
try replacing
while (!inFile.eof())
with
while(getline(inFile, acc[i].acctNum, '#'))
and remove
getline(inFile, acc[i].acctNum, '#');
as first statement in you while

c++ get array string from text file

my text file was like
Jason Derulo
91 Western Road,xxxx,xxxx
1000
david beckham
91 Western Road,xxxx,xxxx
1000
i'm trying to get the data from a text file and save it into arrays however when i want to store the data from the text file into array it loop non-stop. what should i do ? the problem exiting in looping or the method i get the data from text file ?
code:
#include <iostream>
#include <fstream>
using namespace std;
typedef struct {
char name[30];
char address[50];
double balance;
} ACCOUNT;
//function prototype
void menu();
void read_data(ACCOUNT record[]);
int main() {
ACCOUNT record[31]; //Define array 'record' which have maximum size of 30
read_data(record);
}
//--------------------------------------------------------------------
void read_data(ACCOUNT record[]) {
ifstream openfile("list.txt"); //open text file
if (!openfile) {
cout << "Error opening input file\n";
return 0;
} else {
int loop = -1; //size of array
cout << "--------------Data From File--------------"<<endl;
while (!openfile.eof()) {
if (openfile.peek() == '\n')
openfile.ignore(256, '\n');
openfile.getline(record[loop].name, 30);
openfile.getline(record[loop].address, 50);
openfile >> record[loop].balance;
}
openfile.close(); //close text file
for (int i = 0; i <= loop + 1; i++) {
cout << "Account " << endl;
cout << "Name : " << record[i].name << endl;
cout << "Address : " << record[i].address << endl;
cout << "Balance : " << record[i].balance << endl;
}
}
}
Use ifstream::getline() instead of ifstream::eof() in tandem with >>. The following is an illustrative example, (and for simplicity I didn't check to see if the stream opened correctly).
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#define ARR_SIZE 31
typedef struct {
char name[30];
char address[50];
double balance;
} ACCOUNT;
int main() {
ACCOUNT temp, record[ARR_SIZE];
ifstream ifile("list.txt");
int i=0;
double d=0;
while(i < ARR_SIZE) {
ifile.getline(temp.name, 30, '\n');//use the size of the array
ifile.getline(temp.address, 50, '\n');//same here
//consume the newline still in the stream:
if((ifile >> d).get()) { temp.balance = d; }
record[i] = temp;
i++;
}
for (int i=0; i < ARR_SIZE; i++) {
cout << record[i].name << "\n"
<< record[i].address << "\n"
<< record[i].balance << "\n\n";
}
return 0;
}
Another recommendation would be to use vectors for record array, and strings instead of char arrays.
REFERENCES:
Why does std::getline() skip input after a formatted extraction?

reading data from a file into an array of a class

//Student file
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
#include "student.h"
#define cap 100
void main()
{ string s;
class student student[cap],l;
int i;
fstream f;
i=0;
cout << "Enter the file name: "; //Display to enter the file name
cin >>s;
f.open(s.data(),ios::in);
if(!f.is_open())
cout << "could not open file";
while(i<cap && !f.eof())
{ cout << "good";
student[i].get(f);
//Display if okay
if(f.good())
{
i++;
student[i].put(cout);
cout << i;
}
}
f.close();
}
class student
{
public:
student(); //Constructor without parameters
student(int,string,string,int,float); //Constructor with parameters
~student(); //Deconstructors
bool get(istream &); //Input
void put(ostream &); //Output
int read_array(string,int);
private:
int id,age;
float gpa;
string last,first;
};
student::student()
{
id = 0;
first = "null";
last = "null";
age = 0;
gpa = 0.0;
}
bool student::get(istream &in)
{
in >> id >> first >> last >> age >> gpa;
return(in.good());
}
void student::put(ostream &out)
{
out << id << first << last << age << gpa;
}
When i run this It displays the constructor values over, and over and the data from the file that should be going into the array and displaying them. I am not sure if I am doing the right way to put the data into the class array correctly.
Here's one problem:
if (f.good())
{
// student[i] has just been read from the file.
i++; // Increment counter.
student[i].put(cout); // Print whatever was in the next element.
cout << i;
}
The counter is incremented first, so student[i] refers to the element after the one that was just updated.