Home > Mobile >  Empty line at the end of the output
Empty line at the end of the output

Time:12-06

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

  •  Tags:  
  • c
  • Related