0

Here is the message:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 22)
Aborted (core dumped)

And below is my code so far (it's supposed to reformat the names and dates and amounts in a scrambled data file so that it looks like:

Foster, Jerry Lee 1995   329,475

//This program reformats the retirement account data file oldretirement.txt and outputs the data into a new file newretirement.txt


#include<iostream>
#include<cstdlib>
#include<fstream>
#include<cctype>
#include<string>
#include<cstring>
#include<cstddef> 

using namespace std;

void getridof(string &line);
int splitamount(string &line);
int splityear(string &line);
string splitfullname(string &line);

int main(){

 ifstream fin;
 ofstream fout;
 string line;
 string finalname;
 size_t found;
 int finalamount;
 int finalyear;

 fin.open("oldretirement.txt");
 if(fin.fail())
  {cout<< "input file failed to open. \n";
   exit (1);}
 fout.open("newretirement.txt");
 if(fout.fail())
  {cout<<"output file failed to open.\n";
   exit (1);}

while(!fin.eof()){
 getline(fin,line);
// getridof(line); 
 finalamount = splitamount(line);
 finalyear = splityear(line);
 getridof(line);

// found = line.find(",");
// if(found!=string::npos)
 // {finalname = line;}
// else
 // {finalname = splitfullname(line);} 

fout << finalname << finalyear << finalamount << endl;
}
fin.close();
fout.close();
}


void getridof(string &line){
 int location = 0;
 location=line.find("Account$:");
cout << location << endl;
 if(location != 0){
 // location=line.find("Account$:");
  line.erase(location,9);}
 cout<< "get rid of a " << line << endl;
location = line.find("born:");
 if(location != -1){
 // location=line.find("Account$:");
  line.erase(location,5);}
 cout<< "get rid of b " << line << endl;

return;
}

int splitamount(string &line){

 int a;
 size_t found = -1;
 int num_len;
 line.erase(line.find_last_of(","),1);
 cout << "amount a " <<  line << endl;
 found=line.find_last_of((" "));
 num_len=line.length()-found;
 char amount[num_len];
 for(int i=0;i<num_len;i++){
 amount[i] = line[found + 1 + i];
 }
 line=line.substr(0,found);
cout << "amount b " << line<< endl;
 a=atoi(amount);
cout << "amount c "  << a << endl;
 return a;
}

int splityear(string &line){
 char year[4];
 int y;
 size_t found = -1;
cout << "split year a " << line << endl;
 found =  line.find_first_of("1",1);
 for(int i=0;i<4;i++){
year[i] = line[found+i];
 }
 line=line.erase(found,4);
 y=atoi(year);
cout << "split year b " << line << endl;

cout << "split year c " << y << endl;
 return y;
}

string splitfullname(string &line){
 string last;
 string rest = ", ";
 string fullname;
 size_t found = -1;
 found = line.find_last_of(" ");
 last = line.substr(found+1);
// line.erase(found,string::npos);
 rest.insert(3,line);
 fullname = last + rest;
 return fullname;
}

//temp=line.substr(line.first_of("1",0))
//get today's date and subtract integer version of birth dates in data from today's date. (finalyear atoi) (age = currentyear-intyear) do in main.
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
Phoenix Crane
  • 11
  • 1
  • 2
  • Use debugger to determine which line throws the exception. You are using indices incorrectly (your array have 22 elements, and your index is `< 0` or `>= 22`). – Jezor Nov 13 '16 at 04:54

1 Answers1

0

Change :

if(location != 0){

to

if(location != string::npos){

If no matches are found by std::string::find(), the function returns string::npos. npos is a static member constant value with the greatest possible value for an element of type size_t.

That is the reason you are seeing value 18446744073709551615, cause of std::out_of_range`.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • Ok so I made that change and the code compiled more than one of the names in the list, but the error comment didnt go away yet. Do I have to make this change other places? – Phoenix Crane Nov 13 '16 at 05:11
  • Yes. All the places wherever `find()` is invoked. Other option is to do the range check `0 <= index < size()`. – Saurav Sahu Nov 13 '16 at 05:12
  • Ok I'm struggling to understand. All my find() have something in the (), like find("born:"), see line 66. So do I replace what's inside the ()? That does not make sense to me – Phoenix Crane Nov 13 '16 at 05:16
  • Ok would the range check go in the main? – Phoenix Crane Nov 13 '16 at 05:17
  • this is what happens now:terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 0) Aborted (core dumped) – Phoenix Crane Nov 13 '16 at 05:23
  • Read http://stackoverflow.com/questions/3827926/what-does-stringnpos-mean – Saurav Sahu Nov 13 '16 at 05:30
  • I read it but I'm just confused by it. I keep trying random changes but it just gives me errors. I'm really new at this. – Phoenix Crane Nov 13 '16 at 05:43