c++ Vector subscript out of range error - c++

The program is supposed to open a .csv file and input the data into a vector. Later I'm supposed to implement a priority queue. However I'm getting this error when I try to run it.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include "Prisoner.h"
#include "Jailed.h"
using namespace std;
int main()
{
string line, ID, sentenceIn, servedIn, lastName, firstName;
int sentence, served;
vector<string> idNum;
vector<int> sentenceLen;
vector<int> servedTime;
vector<string> lastNameIn;
vector<string> firstNameIn;
ifstream data("prisoner_data.csv");
if (!data.is_open())
{
exit(EXIT_FAILURE);
}
while (getline(data, line))
{
getline(data, ID, ',');
cout << ID << " ";
idNum.push_back(ID);
getline(data, sentenceIn, ',');
cout << sentenceIn << " ";
istringstream(sentenceIn) >> sentence;
sentenceLen.push_back(sentence);
getline(data, servedIn, ',');
cout << servedIn << " ";
istringstream(servedIn) >> served;
servedTime.push_back(served);
getline(data, lastName, ',');
lastNameIn.push_back(lastName);
cout << lastName << " ";
getline(data, firstName, ',');
firstNameIn.push_back(firstName);
cout << firstName << " ";
}
Prisoner p[100]; // Initializing Prisoner class
for (int i = 0; i <= idNum.size(); i++)
{
p[i].setIdNum(idNum[i]);
p[i].setSentence(sentenceLen[i]);
p[i].setTimeServed(servedTime[i]);
p[i].setLastName(lastNameIn[i]);
p[i].setFirstName(firstNameIn[i]);
}
data.close();
system("pause");
return 0;
}
I can also include the prisoner class if needed to figure out the issue.

for (int i = 0; i <= idNum.size(); i++)
should be
for (int i = 0; i < idNum.size(); i++)

Related

How to read, write parent class & Inherited class's data to a binary file in C++ altogether? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed yesterday.
This post was edited and submitted for review 12 hours ago.
Improve this question
I am working on a routine management system. I just thought like this, the binary file will have 8 lines, 1st line for password matching (8 characters fixed, drama for college), rest of the lines will have the timetable for each day and each line no corresponds to the day no.
Now I made 1 TimeTable Class and a Inherited class Period. Timetable holds day no and Period holds all the details of a period like faculty id, time, sub code, etc.
Now, problem is, how can I write & read the whole data to & from the binary file?
Also, how can I display the whole routine like spreadsheet?
I separated the modules as I have also made login & signup features (module) in my code.
To view the full project you can check my GitHub Repo: https://github.com/ArchismanKarmakar/TimeTable-AK
UPDATE:
Well I just made the modules for faculty. After research, I found that saving a whole routine & getting it in formatted form is impossible with binary files. So, I just switched to CSV / TXT files.
Just made the Faculty modules:
I made the facultyId.csv like this:
id,name,age,phone,email,gender
a12,archisman,0000000000,test#test.com,M\n
But I wanted to represent the whole 2D matrix of routine in the CSV file. Is that possible?
Faculty.hh
#ifndef FACULTY
#define FACULTY
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
#include <set>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include <chrono>
#include <random>
#include <functional>
#include <limits>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <./../include/global.hh>
using namespace std;
class Faculty // ABSTRACT CLASS
{
protected:
string id;
string name;
int16_t age;
string phone;
string email;
char gender;
public:
Faculty();
void addFaculty(int16_t minAge = 18, int16_t maxAge = 100);
void removeFaculty();
void editMap();
void fillMap();
};
#endif
Faculty.cpp
#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
#include <set>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include <chrono>
#include <random>
#include <functional>
#include <limits>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <./../include/faculty.hh>
#include <./../include/global.hh>
using namespace std;
Faculty::Faculty()
{
id = -1;
}
void Faculty::addFaculty(int16_t minAge, int16_t maxAge)
{
cout << "\nEnter Id: \n";
getline(cin >> ws, id);
if (std::filesystem::exists("./data/" + id + ".csv"))
return void(cout << "Sorry, this Faculty ID is already registered.\n");
cout << "\nEnter name: ";
getline(cin >> ws, name);
cout << "\nEnter age: \n";
cin >> age;
while (age <= 0)
{
cout << "Was that supposed to make any kind of sense?\nEnter again!\n", cin >> age;
if (age < minAge)
return void(cout << "Sorry, person should be at least " << minAge << " years old to be registered.\n");
else if (age > maxAge)
return void(cout << "Sorry, we can't register a person older than " << maxAge << " years.\n");
}
cout << "\nEnter mobile number (with country code): \n";
getline(cin >> ws, phone);
cout << "\nGender (M = Male || F = Female): \n";
cout << "\nEnter email: \n";
getline(cin >> ws, email);
cin >> gender;
while (gender != 'M' && gender != 'F')
cout << "M or F?\n", cin >> gender;
fstream f;
string path = "./data/" + id + ".csv";
f.open(path, ios::in);
// `le first line conataining column headers:
// f << "Id,Name,age,phone,email,gender\n";
// for (auto i : Faculty::appointmentsList)
f << id << name << "," << age << "," << phone << "," << email
<< "," << gender << endl;
f.close();
// add.takeInput();
return;
}
void Faculty::fillMap()
{
string id;
cout << "\nEnter Id to fill: \n";
cin >> id;
if (!std::filesystem::exists("./data/" + id + ".csv"))
return void(cout << "Sorry, this Faculty ID is not registered.\n");
fstream f;
string path = "./data/" + id + ".csv";
f.open(path, ios::in);
string temp;
// //skipping the first row containing column headers;
// getline(f >> ws, temp);
// analyzing each entry afterwards;
(getline(f >> ws, temp));
{
Faculty a;
// creating a string stream object to read from string 'temp';
stringstream s(temp);
string s1, s5, s6, s7;
// reading from the string stream object 's';
getline(s, a.id, ',');
getline(s, a.name, ',');
getline(s, s1, ',');
getline(s, a.phone, ',');
getline(s, a.email, ',');
// getline(s, a.gender, ',');
getline(s, s7, ',');
a.age = strToNum(s1);
a.gender = s7[0];
// if (!a.idle)
// {
// a.add.strToAdd(s6);
// a.D = Faculty::driversList[strToNum(s7)];
// }
// Faculty::FacultyList[a.id] = a;
}
f.close();
return;
}
void Faculty::editMap()
{
string id;
cout << "\nEnter Id to edit: \n";
cin >> id;
if (!std::filesystem::exists("./data/" + id + ".csv"))
return void(cout << "Sorry, this Faculty ID is not registered.\n");
fstream f;
string path = "./data/" + id + ".csv";
f.open(path, ios::in);
string temp;
// //skipping the first row containing column headers;
// getline(f >> ws, temp);
// analyzing each entry afterwards;
(getline(f >> ws, temp));
{
// Faculty a;
// creating a string stream object to read from string 'temp';
stringstream s(temp);
string s1, s5, s6, s7;
// reading from the string stream object 's';
getline(s, id, ',');
getline(s, name, ',');
getline(s, s1, ',');
getline(s, phone, ',');
getline(s, email, ',');
// getline(s, a.gender, ',');
getline(s, s7, ',');
age = strToNum(s1);
gender = s7[0];
}
f.close();
int choice = 0;
while (choice != 5)
{
cout << "\nWhat do you want to edit?\n";
cout << "1. Name\n";
cout << "2. Age\n";
cout << "3. Phone\n";
cout << "4. Email\n";
cout << "5. Gender\n";
cout << "6. Exit\n";
cin >> choice;
switch (choice)
{
case 1:
{
cout << "\nEnter name: ";
getline(cin >> ws, name);
break;
}
case 2:
{
cout << "\nEnter age: \n";
cin >> age;
while (age <= 0)
{
cout << "Was that supposed to make any kind of sense?\nEnter again!\n", cin >> age;
if (age < 18)
return void(cout << "Sorry, person should be at least 18 years old to be registered.\n");
else if (age > 100)
return void(cout << "Sorry, we can't register a person older than 100 years.\n");
}
break;
}
case 3:
{
cout << "\nEnter mobile number (with country code): \n";
getline(cin >> ws, phone);
break;
}
case 4:
{
cout << "\nEnter email: \n";
getline(cin >> ws, email);
break;
}
case 5:
{
choice = 5;
break;
}
default:
{
return void(cout << "Invalid choice!\n");
break;
}
}
}
remove((char *)path.c_str());
fstream f;
string path = "./data/" + id + ".csv";
f.open(path, ios::out);
f << id << name << "," << age << "," << phone << "," << email
<< "," << gender << endl;
f.close();
// `le first line conataining column headers:
// f << "Id,Name,age,phone,email,gender\n";
// for (auto i : Faculty::appointmentsList)
// f << id << "," << yyyymmdd << "," << i.second.D.id << "," << i.second.P.id
// << "," << i.second.hh << endl;
// f.close();
// rename("./data/temp.csv", "./data/appointments.csv");
return;
}
void removeFaculty()
{
string id;
cout << "\nEnter Id to edit: \n";
cin >> id;
if (!std::filesystem::exists("./data/" + id + ".csv"))
return void(cout << "Sorry, this Faculty ID is not registered.\n");
remove((char *)("./data/" + id + ".csv").c_str());
return void(cout << "Faculty removed successfully!\n");
}

For loop returning process after 2nd iteration

I'm writing code to take a player's name as input, search a csv file for the name and if the file contains the name save the entire row to a vector within a vector to be accessed later. However the process is returned after the 2nd iteration of the for loop (it's supposed to loop 11 times). Any help is appreciated! Here's the code:
[#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
#include "fantasy.h"
using namespace std;
player::player(void)
{
NULL;
}
void player::playerinput(void)
{
playername = " ";
playern2 = " ";
int count = 0;
fileName = " ";
for(int i=0; i<11; i++){
std::cout << "Enter player second name: ";
std::cin >> playername;
player::opencsv(playername);
}
}
void player::opencsv(string playername){
count = 0;
run = true;
string line, word, temp;
vector<string> row = {};
fin.open("C:/Users/Desktop/CSProject/cleaned_players 1819.csv", ios::in);
while(run){
row.clear();
getline(fin, line);
stringstream s(line);
while (getline(s, word, ',')){
row.push_back(word);
}
playern2 = row\[1\];
if(playern2 == playername){
count = 1;
players.push_back(row);
std::cout << "Player: " << row\[0\] << " " << row\[1\] << " added to database" << std::endl;
run = false;
return;
}
if(count = 0){
std::cout << "Player not in database" << std::endl;
return;
}
}
row.clear();
fin.clear();
}
int main()
{
player P1;
P1.playerinput();
}
1

C++ Searching for a word in a CSV file

I am trying to create a program that stores data from a CSV file and then searches it for key words.
I have this code, and there are no errors shown, but it wont run the program past asking for 'Enter word: '
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], ',');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count;
return 0;
}
In order to get std::cin to contain the exact string (multiple words?) that the user inputs, you can use std::getline() which will support more than one word specified by the user. It's not clear from your problem statement if this is what you want or not. Otherwise I don't see a problem with just using std::cin if all you're looking for is a single word of input.
std::string match;
std::cout << "Enter the exact string to search for: ";
std::getline(std::cin, match);
std::cout << "\nSearching for \"" << match << "\"" << std::endl;
Also, in your for loop for searching the answer strings, you should prefer to use the built in size of the vector you're looping through as opposed to a hard coded value.
for ( size_t j = 0; j < answer.size(); ++j )
{
std::size_t found = answer[j].find(match);
if (found != std::string::npos)
{
std::cout << "found \"" << match
<< "\" starting at character " << found << std::endl;
count++;
}
}
std::cout << "occurrences of match criteria: " << count << std::endl;
the error is in getline, the first call to it, extracts the word until the comma the second call until the 2nd comma, the 3r call to third comma past the to the next new line (the next student's name).
So the next iteration in the getline call, will fetch the question as the students name then the answer as the question then the next students name as the answer, a total mess!!! ;) So you will never find the word you are looking for, thus no result. Get it?
to fix this, try to change the last getline to getline(file, answer[i]);
So, I know this is not the best way to solve the problem. But, in a time crunch I was able to fix these few errors and add a system("pause"); at the end of my code so that it would let me see the results.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], '\n');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count << endl;
system("pause");
return 0;
}

C++ reading from a .txt file line by line string and number data type on each line

So I am trying to read a .txt file in c++ program. Each line in the text file has firstName, lastName and yearlySalary (e,g, Tomm Dally, 120000).
I can seem to read a file properly - it skips the first column (firstName) and stops reading the data in after first line. Why is that?
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
string fName;
string lName;
double yearlyPay;
double backPayDue;
double newAnualSalary;
double newMonthlyWage;
int numOfEmployees = 0;
double totalBackPayDue = 0;
ifstream empSalariesOld("EmpSalaries.txt");
ofstream empSalariesNew("EmpSalariesNew.txt");
if (!empSalariesOld.fail())
{
while (empSalariesOld >> fName)
{
empSalariesOld >> fName >> lName >> yearlyPay;
std::cout << fName << " " << lName << " " << yearlyPay << endl;
numOfEmployees++;
}
}
empSalariesOld.close();
empSalariesNew.close();
system("pause");
return 0;
}
You are not reading the lines correctly.
When your while statement calls empSalariesOld >> fName for the first time, it reads an employee's first name. Then, inside the loop body, when you call empSalariesOld >> fName >> lName >> yearlyPay, >> fName reads the employee's last name (because you already read the first name), then >> lName reads the employee's salary, and >> yearlyPay tries to read the next employee's first name and fails!
Try something more like the following instead. Use std::getline() to read a whole line, and then use std::istringstream to parse it:
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string fName;
string lName;
double yearlyPay;
//...
int numOfEmployees = 0;
ifstream empSalariesOld("EmpSalaries.txt");
ofstream empSalariesNew("EmpSalariesNew.txt");
if (empSalariesOld)
{
string line;
while (getline(empSalariesOld, line))
{
istringstream iss(line);
if (iss >> fName >> lName >> yearlyPay) {
std::cout << fName << " " << lName << " " << yearlyPay << endl;
++numOfEmployees;
}
}
}
empSalariesOld.close();
empSalariesNew.close();
cout << "Press any key";
cin.get();
return 0;
}
However, if the lines actually have a comma between the name and salary like you showed (Tomm Dally, 120000), then try the following instead:
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
string name;
double yearlyPay;
//...
int numOfEmployees = 0;
ifstream empSalariesOld("EmpSalaries.txt");
ofstream empSalariesNew("EmpSalariesNew.txt");
if (empSalariesOld)
{
string line;
while (getline(empSalariesOld, line))
{
istringstream iss(line);
if (getline(iss, name, ',') && (iss >> yearlyPay))
std::cout << name << " " << yearlyPay << endl;
++numOfEmployees;
}
}
}
empSalariesOld.close();
empSalariesNew.close();
cout << "Press any key";
cin.get();
return 0;
}

C++ String Array to Text Document

I am trying to create a program that will make an array of data entered until a stop commands is entered and have it log it into a text document. I am getting a crash of Microsoft Visual Studio after i enter the Fist name and Last name fields.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
int main(void) {
string firstName;
string lastName;
string stream;
int outputString;
string dataOutput;
string dataArray[1];
bool askData = true;
int i = 0;
ofstream outfile("data.txt");
while (askData) {
cout << "Type First then Last Name or \"$Stop\" to save and exit" << "\n" << "First: ";
getline(cin, firstName);
if (firstName == "$Stop") {
askData = false;
}
else {
cout << "Last: ";
cin >> lastName;
cout << "\n\n\n";
dataOutput = firstName + " " + lastName + "; ";
dataArray [1 + i] = dataOutput;
i++;
}
cout << dataOutput;
}
outfile << dataArray;
outfile.close();
return 0;
}
EDIT:
Also tried.
string dataArray[];
then later assigning it to an incrementing variable.
int i = 0;
dataArray[i];
i++;
Can you tell me why this doesnt work?