I'm currently having an issue navigating a txt file so I can read it into an array. The program compiles fine, but when I run it returns in terminal:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 14)
Aborted (core dumped)
Here is the code:
#include<cstdlib>
#include<cmath>
#include<fstream>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<cassert>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<locale.h>
#include<stdio.h>
#include<functional>
#include<math.h>
using namespace std;
int main(int argc, char**argv)
{
int r=0;
int p=0;
int c=0;
string names[20];
double scores[20][10];
ifstream infile;
infile.open("./bowlers.txt");
for(int r=1;r<=10;r++)
{
getline(infile,names[r]);
p=names[r].find_first_of("\n") ;
names[r].erase(p,2);
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
infile.ignore(100,'\n');
}
infile.close();
for(int r=1;r<=10;r++)
{
cout<<fixed<<setprecision(2)<<endl;
cout<<names[r]<<endl;
}
return 0;
}
The txt file I'm using looks like this:
charles
123
321
222
rose
432
515
123
Greg
123
553
136
So here is what I have found out in researching this problem myself:
Part of my problem is that:
p=names[r].find_first_of('\n') ;
names[r].erase(p,2);
Is causing the issue, because \n
is never found it returns -1, and you can't .erase
-1?
I have tried using every conceivable of \r,
\n
, \r\n
, etc. and I always recieve roughly the same output. I have also tried changing the encoding of the .txt file. The only difference is in (which is 14)
. The number will fluctuate depending on how I encode the .txt file. Also I have opened the .txt file in vim and :set list
to see the newline characters. So I know they are there.
This is just partial code of a much larger project for school, and I am not very experienced with c++ yet. Can anyone point me in the right direction? I feel like once I get this portion of my code figured out I should be able to finish the project.
NOTE: the txt file is just an example so do not put too much thought into the size of my arrays or the parameters in my for loop. I have triple checked the sizes of my arrays to make sure there were no issues with me trying to read into a row that didnt exist.
Always check the return of value of find functions. Example:
size_t p = names[r].find_first_of("\n");
if (p != string::npos)
names[r].erase(p, 2);
If \n
is not found, the return value is string::npos
(it could be 0xFFFFFFFF
or 0xFFFFFFFFFFFFFFFF
) which is invalid index. Attempting to access that index results in error.
As noted in comments, names[r]
does not contain \n
in this case. p
is always string::npos
and this operation is not required.
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
You only have 3 integers below each name, so you should count to 3, not 5. This code should work:
for(int r = 1; r <= 10; r++)
{
getline(infile, names[r]);
for(int c = 1; c <= 3; c++)
infile >> scores[r][c];
infile.ignore(100, '\n');
}
Or you can add more error checking, example if (!(infile >> scores[r][c])) break;