C++ Read file line by line then split each line using the delimiter

Viewed 106337

I want to read a txt file line by line and after reading each line, I want to split the line according to the tab "\t" and add each part to an element in a struct.

my struct is 1*char and 2*int

struct myStruct
{
    char chr;
    int v1;
    int v2;
}

where chr can contain more than one character.

A line should be something like:

randomstring TAB number TAB number NL
4 Answers

I had some difficulty following some of the suggestions here, so I'm posting a complete example of overloading both input and output operators for a struct over a tab-delimited file. As a bonus, it also takes the input either from stdin or from a file supplied via the command arguments.

I believe this is about as simple as it gets while adhering to the semantics of the operators.


pairwise.h

#ifndef PAIRWISE_VALUE
#define PAIRWISE_VALUE

#include <string>
#include <iostream>

struct PairwiseValue
{
    std::string labelA;
    std::string labelB;
    float value;
};

std::ostream& operator<<(std::ostream& os, const PairwiseValue& p);

std::istream& operator>>(std::istream& is, PairwiseValue& p);

#endif

pairwise.cc

#include "pairwise.h"

std::ostream& operator<<(std::ostream& os, const PairwiseValue& p)
{
    os << p.labelA << '\t' << p.labelB << '\t' << p.value << std::endl;
    return os;
}

std::istream& operator>>(std::istream& is, PairwiseValue& p)
{
    PairwiseValue pv;

    if ((is >> pv.labelA >> pv.labelB >> pv.value))
    {
        p = pv;
    }

    return is;
}

test.cc

#include <fstream>
#include "pairwise.h"

int main(const int argc, const char* argv[])
{
    std::ios_base::sync_with_stdio(false); // disable synch with stdio (enables input buffering)

    std::string ifilename;
    if (argc == 2)
    {
        ifilename = argv[1];
    }

    const bool use_stdin = ifilename.empty();
    std::ifstream ifs;
    if (!use_stdin)
    {
        ifs.open(ifilename);

        if (!ifs)
        {
            std::cerr << "Error opening input file: " << ifilename << std::endl;
            return 1;
        }
    }

    std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : std::cin;

    PairwiseValue pv;

    while (is >> pv)
    {
        std::cout << pv;
    }

    return 0;
}

Compiling

g++ -c pairwise.cc test.cc
g++ -o test pairwise.o test.o

Usage

./test myvector.tsv
cat myvector.tsv | ./test
Related