So I have a "db.csv" data file. Code reads each value from the file separated by a comma (value1, ...). Unnecessary spacings from the lines are deleted, then the finished line is printed out as desired (one space between values). The problem is that I have to pass the tests on a site called repl.it. And I fail every test, because there is an extra blank line at the end of the output. Any suggestions? I know, that it's probably because of the endl at the cout, but how else do I do it?
Minimal reproducible code:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
using namespace std;
int main() {
fstream file("db.csv", ios::in);
string value1, value2, value3, value4, value5, line;
cout << "result:" << endl;
while (getline(file, line)) {
if (line.length() > 1) {
istringstream str1(line);
while (getline(str1, value1, ','),
getline(str1, value2, ','),
getline(str1, value3, ','),
getline(str1, value4, ','),
getline(str1, value5, '\n')) {
value1.erase(remove(value1.begin(), value1.end(), ' '), value1.end());
value2.erase(remove(value2.begin(), value2.end(), ' '), value2.end());
value3.erase(remove(value3.begin(), value3.end(), ' '), value3.end());
value4.erase(remove(value4.begin(), value4.end(), ' '), value4.end());
value5.erase(remove(value5.begin(), value5.end(), ' '), value5.end());
cout << value1 << " " << value2 << " "
<< value3 << " " << value4 << " "
<< value5
<< endl;
}
}
}
}
db.csv file data:
Riga,Kraslava,Pr,15:00,11.00
Riga ,Kraslava,Pr ,18:00,11.00
Kraslava,Riga,Pr,08:00,11.00
Kraslava,Daugavpils,Ot ,10:00, 3.00
Ventsplis,8.00,Liepaja,Sv,20:00
Dagda,Sv
Rezekne,Riga,Tr,13:00,10.50
Dagda,Kraslava, Ce,18:00, 2.50
Dagda,Kraslava,Ce,18:00,2.50,Sv
Riga,Ventspils, Pt,09:00 , 6.70
Liepaja,Ventspils,Pt,17:00,5.50
Output:
Riga Kraslava Pr 15:00 11.00
Riga Kraslava Pr 18:00 11.00
Kraslava Riga Pr 08:00 11.00
Kraslava Daugavpils Ot 10:00 3.00
Ventsplis 8.00 Liepaja Sv 20:00
Rezekne Riga Tr 13:00 10.50
Dagda Kraslava Ce 18:00 2.50
Dagda Kraslava Ce 18:00 2.50,Sv
Riga Ventspils Pt 09:00 6.70
Liepaja Ventspils Pt 17:00 5.50
*blank line*
Desired output:
Riga Kraslava Pr 15:00 11.00
Riga Kraslava Pr 18:00 11.00
Kraslava Riga Pr 08:00 11.00
Kraslava Daugavpils Ot 10:00 3.00
Ventsplis 8.00 Liepaja Sv 20:00
Rezekne Riga Tr 13:00 10.50
Dagda Kraslava Ce 18:00 2.50
Dagda Kraslava Ce 18:00 2.50,Sv
Riga Ventspils Pt 09:00 6.70
Liepaja Ventspils Pt 17:00 5.50
CodePudding user response:
Rather than detect the last iteration and avoid putting a newline, it might be easier if you add the newline at the start of the loop and to avoid an extraneous newline at the start of the output, keep a Boolean variable is_first
initially set to true
and at the start of your loop body have
if (!is_first)
cout << endl;
is_first = false;
Ain’t pretty but it’s quick to code.
CodePudding user response:
I think this approach is cleaner:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
using namespace std;
std::string filedata = R"(
Riga,Kraslava,Pr,15:00,11.00
Riga ,Kraslava,Pr ,18:00,11.00
Kraslava,Riga,Pr,08:00,11.00
Kraslava,Daugavpils,Ot ,10:00, 3.00
Ventsplis,8.00,Liepaja,Sv,20:00
Dagda,Sv
Rezekne,Riga,Tr,13:00,10.50
Dagda,Kraslava, Ce,18:00, 2.50
Dagda,Kraslava,Ce,18:00,2.50,Sv
Riga,Ventspils, Pt,09:00 , 6.70
Liepaja,Ventspils,Pt,17:00,5.50
)";
std::string trim( const std::string& str ) {
std::size_t pos = str.find_first_not_of( " \t" );
if ( pos == std::string::npos ) return {};
std::size_t last = str.find_last_not_of( " \t" );
if ( last == std::string::npos ) return {};
return str.substr( pos, last - pos 1 );
}
std::vector<std::string> split( const std::string& line ) {
std::size_t pos = 0;
std::size_t next = 0;
std::vector<std::string> fields;
while ( next != std::string::npos ) {
next = line.find_first_of( ',', pos );
std::string field = next == std::string::npos ? line.substr(pos) : line.substr(pos,next-pos);
fields.push_back( trim( field ) );
pos = next 1;
}
return fields;
}
int main()
{
istringstream file(filedata);
cout << "result:" << endl;
std::string line;
while (getline(file, line)) {
if (!line.empty()) {
auto fields = split( line );
for ( std::string field : fields ) {
cout << field << ",";
}
cout << endl;
}
}
}
Results in
result:
Riga,Kraslava,Pr,15:00,11.00,
Riga,Kraslava,Pr,18:00,11.00,
Kraslava,Riga,Pr,08:00,11.00,
Kraslava,Daugavpils,Ot,10:00,3.00,
Ventsplis,8.00,Liepaja,Sv,20:00,
Dagda,Sv,
Rezekne,Riga,Tr,13:00,10.50,
Dagda,Kraslava,Ce,18:00,2.50,
Dagda,Kraslava,Ce,18:00,2.50,Sv,
Riga,Ventspils,Pt,09:00,6.70,
Liepaja,Ventspils,Pt,17:00,5.50,
Compiler explorer: https://godbolt.org/z/enheGdjda