I am trying to use std::getline()
in my project to read in a text file into an array of strings.
Here is my code:
ifstream ifs ( path );
string * in_file;
int count = 0;
while ( !ifs.eof() )
{
++count;
if ( count == 1 )
{
in_file = new string[1];
}
else
{
// Dynamically allocate another space in the stack
string *old_in_file = in_file;
in_file = new string[count];
// Copy over values
for ( int i = 0 ; i < ( count - 1 ) ; i++ )
{
in_file[i] = old_in_file[i];
}
delete[] old_in_file;
}
// After doing some debugging I know this is the problem what am I
// doing wrong with it?
getline(ifs,in_file[count - 1]);
}
So after doing some decoding I know that the getline() is not placing any value in the array of strings. It seems to place a null string in the array.
The goal is to read in a text file like:
Hello
Bye
See you later
The array will be filled like:
in_file [0] = Hello
in_file [1] = Bye
in_file [2] = See you later
Never wrap reading from the stream with the following loop:
while ( !ifs.eof() )
At some websites, you will find an example telling you to do:
while ( ifs.good() )
which is a bit better than the first loop, yet still it is quite error prone and not advisable to do. Have a look at: Why is iostream::eof inside a loop condition considered wrong?
The most common ways of reading the files are either using std::getline
when reading by lines:
std::string line;
while ( std::getline(ifs, line) ) {
if (line.empty()) // be careful: an empty line might be read
continue;
...
}
or simply using >>
operator when reading by words or extracting concrete types (e.g. numbers):
std::string word;
while ( ifs >> word ) {
...
}
And to your dynamically allocated C-style array of std::string
objects: avoid dynamic allocation as much as possible. Believe me, you don't want to take care of memory management on your own. Prefer using objects with automatic storage duration. Take advantage of what the standard library provides.
As it was pointed out already: use STL containers such as std::vector
instead of C-style arrays:
std::ifstream ifs(path);
std::vector<std::string> lines;
std::string line;
while ( std::getline(ifs, line) )
{
// skip empty lines:
if (line.empty())
continue;
lines.push_back(line);
}