I have to read in this order, an int and then a string on a text file which contains multiple lines
My issue is: I'm guessing eof counts as a char to read? So when my program is reading the elements and storing them into their appropriate variables, it will read the eof, putting a complete int junk onto my array. I think this is crashing my program
void CopyData(string Fname, int &cap)
{
PriorityQueue Data;
string names[50];
int pq[50];
int size = 0;
fstream f;
f.open(Fname, ios::in);
while (!f.eof() && pq[size] != NULL) //as long as we are not at end of file
{
f >> pq[size];
getline(f, names[size]);
Data.insert(names[size], pq[size]);
cout << pq[size] << " " << names[size] << endl;
size++;
}
f.close();
cout << size; //to account for end of flag char
delete[] names;
delete[]pq;
}
You either can read a line, or not. Accept no partials.
While macro NULL does expand to 0, is it really the intuitive way to compare against an int?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
constexpr size_t N {50};
int pq[N];
std::string names[N];
size_t size {0};
int num;
char dummy;
std::string text;
std::ifstream f( Fname );
while ( size < N && f >> num >> dum && std::getline( f, text ) ) {
// we get into loop if and only if the read of both num and text was a success
// and there is room to write them to
pq[size] = num;
names[size++] = text;
}
The problem is also because you are looping on EOF.
The correct loop should always be functionally equivalent to:
1 2 3 4 5 6
loop
{
attempt to read from file; // 1
if (failed to read) break; // 2
do stuff;
}
C++ tends to make this very easy, since things like getline(...) and cin >> foo return the stream as a result of their function, so they do both 1 and 2.
1 2 3 4
while (getline( f, s )) // 1: read into s, 2: break on fail
{
...
}
1 2 3
while (cin >> x) // 1: read into x, 2: break on fail
{
}
You can typically design input classes or functions to do it just as conveniently.
Otherwise you must write the loop out in all its gory detail. For example, this reads a bunch of integers, each on its own line with nothing else, and complains if anything went wrong:
vector <int> ns;
while (true)
{
int n;
string s;
if (!getline( f, s )) break;
istringstream ss( trim( s ) );
ss >> n;
if (!ss.eof())
{
f.setstate( ios::failbit );
break;
}
ns.push_back( n );
}
if (!f.eof())
{
cout << "Something went wrong.\n";
return 1;
}