I would like to give thanks to everyone who helped me with my problem. I was finally able to arrange the data by birth year! Very much appreciated. If anyone can help me with this final question, that'd be great
If I have lines in a text file that look like this:
1 4:48:08 Orvar Steingrimsson 1979 30 - 39 ara IS200
2 4:52:25 Gudni Pall Palsson 1987 18 - 29 ara IS870
How can I output this data onto a new text file but only listing three things: year - name - time ... so that these two lines would look like this:
1979 Orvar Steingrimsson 4:48:08
1987 Gudni Pall Palsson 4:52:25
My guess was this:
ifstream in("inputfile.txt");
ofstream out("outputfile.txt");
int score, year;
string name, time, group, team;
while (getline(in,str));
in >> score >> time >> name >> year >> group >> team;
//and then do something like this
out << year << name << time << '\n';
However I have a feeling I won't be able to loop this through the whole text file and all 200 lines. Any tips appreciated! Thanks
"I know that the year is always the 54th to 58th character in each line"
So, consider this :
int main ()
{
ifstream in("laugavegurinn.txt", ios::in);
ofstream out("laugavegurinn2.txt");
string str;
multimap<int, string> datayear;
while (getline(in,str)) {
int year = stoi(str.substr(54, 4));
datayear.insert(make_pair(year,str)); //use insert function
// multimap don't have [] operator
}
for (auto v : datayear)
out << v.second << "\n";
in.close();
out.close();
}
For starters, read the lines into an std::vector<std::string>
,
using std::getline
. Then sort them in the desired order.
Then output them. So main
becomes basically three lines:
std::vector<Line> data( readLines( inFile ) );
sortByBirthYear( data );
std::copy( data.begin(), data.end(), std::ostream_iterator<std::string>( outFile, "\n" ) );
Of course, readLines
and sortByBirth
need to be written as
well, but they're both fairly trivial as well.
Alternatively, and probably better, you could define
a DataLine
class with an operator>>
, and operator<<
and
a comparison function (operator<
), and then all you'd need is:
std::vector<DataLine> data(
(std::istream_iterator<DataLine>( inFile )),
(std::istream_iterator<DataLine>()) );
std::sort( data.begin(), data.end() );
std::copy( data.begin(),
data.end(),
std::ostream_iterator<std::string>( outFile, "\n" ) );
That's what I'd do, but if you've just started C++, you may not
have covered the necessary basics yet, like classes and operator
overloading.
One thing I'd also add, based on your code: don't ever access
data you've input without first checking that the input
succeeded.
EDIT (implementation using just the basic functionality):
As above (but without the Line
type):
std::vector<std::string> data( readLines( inFile ) );
std::sort( data.begin(), data.end(), orderByBirthYear );
std::copy( data.begin(), data.end(),
std::ostream_iterator<std::string>( outFile, "\n" ) );
with:
std::vector<std::string>
readLines( std::istream& source )
{
std::vector<std::string> results;
std::string line;
while ( std::getline( source, line ) ) {
results.push_back( line );
}
return results;
}
bool
orderByBirthYear( std::string const& lhs, std::string const& rhs )
{
return lhs.compare( 54, 4, rhs, 54, 4 ) < 0;
}
But I insist: this is not how one should solve it. Any
reasonable solution would start by defining a class for your
data, and define all of the operations using this. This means
not just defining a class
, but also operator overloading; if
you've just started, you likely haven't seen any of these yet
(and the assignment is not a good sign with regards to the
quality of the course).
For the rest, you're on the right track; for line oriented
input, you should read using getline
. After that, however,
the line has been extracted from the input; to parse it further,
you need to initialize an std::istringstream
with it, and read
from that. Except that your input format seems to be based on
columns, so you'd probably use the substr
function of
std::string
to get the individual fields. Once you've got
them, you'll want to strip leading and trailing white space, and
maybe convert to numeric types (although for just sorting by
year, this is not necessary). But all of this would logically
occur in a user defined operator>>
to a Data
class.
(Similarly, you'd provide a user defined operator<<
to write
the sorted data out. And typically, orderByBirthYear
, above,
would be a class as well.)