HiveBrain v1.2.0
Get Started
← Back to all entries
debugcppMinor

Reading three rows of six tab-separated numbers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
threerowsreadingsixtabnumbersseparated

Problem

I've just posted this solution in my review of @adrienlucca's question, which is to read three rows of six tab-separated doubles.

#include 
#include 
#include 
#include 

struct Sexdoublet {
    double x, y, d, m, c, t;

    friend std::istream &operator>>(std::istream &in, Sexdoublet &r) {
        return in >> r.x >> r.y >> r.d >> r.m >> r.c >> r.t;
    }

    friend std::ostream &operator import(std::istream &in) {
    std::vector data;
    Sexdoublet s;
    do {
        in >> s;
    } while (in && (data.push_back(s), true));
    return data;
}

int main(int argc, char *argv[]) {
    // If the first command-line argument is not "-", treat it as the filename
    // from which to read the input.  Otherwise, read from STDIN.
    const char *filename = (argc >= 2 && 0 != strcmp("-", argv[1])) ?
                                argv[1] : NULL;
    std::ifstream f;
    std::istream &in = filename ? (f.open(filename), f) : std::cin;
    if (!f) {
        std::cerr  data = import(in);
    std::for_each(data.begin(), data.end(), [](const Sexdoublet &s) {
        std::cout << s << std::endl;
    });
    return 0;
}


I ended up using the comma operator twice — both times as a "workaround" for the fact that a function I call returns void:

  • (data.push_back(s), true) — I have to check whether the istream extractions succeeded before adding an element to the result.



  • (f.open(filename), f) — I like the ternary operator because it expresses the fact that in is going to be assigned to one value or another. Also, the in reference has to be initialized immediately and irrevocably, right?



It is my impression that the comma operator is rarely used in C and C++. So, I'd like to ask, are these reasonable uses of the comma operator? Or too clever? Or too dumb, because I've missed an entirely better solution?

Solution

the first use can be replaced with:

while(in >> s) {
    data.push_back(s)
}


the second case is much more readable with a simple if else:

std::ifstream f;
if(argc >= 2 && 0 != strcmp("-", argv[1])) {
    f.open(argv[1]);
    if (!f) {
        std::cerr << "Error opening " << argv[1] << ": "
                  << strerror(errno) << std::endl;
        return 1;
    }

}
std::istream &in = f.is_open() ? f : std::cin;

Code Snippets

while(in >> s) {
    data.push_back(s)
}
std::ifstream f;
if(argc >= 2 && 0 != strcmp("-", argv[1])) {
    f.open(argv[1]);
    if (!f) {
        std::cerr << "Error opening " << argv[1] << ": "
                  << strerror(errno) << std::endl;
        return 1;
    }

}
std::istream &in = f.is_open() ? f : std::cin;

Context

StackExchange Code Review Q#35331, answer score: 4

Revisions (0)

No revisions yet.