procatmer
procatmer

Reputation: 5649

Reading data from file C++

I have these set of data in .txt log file:

2016-01-17 Red 1 2 2.252016-01-18 blue 3 1 1.34

I stored it to vector, and the code looks like this:

while(!logFile.eof()) {
    getline(logFile, l.date, ' ');
    getline(logFile, l.color, ' ');
    logFile >> l.minUsage;
    logFile >> l.maxUsage;
    logFile >> l.ratio;
    logFile.ignore(1000, ' ');

    log.push_back(l);
}

log's datatype is vector<Record> where Record is a class. I wanted the values to look like this when I'm printing it:

2016-01-17 Red  1 2 2.25
2016-01-18 blue 3 1 1.34

but instead I got this output:

2016-01-17 Red  1 2 2.25
blue 3 1 0 1.34

the second line doesn't store the value of the date from second set of data from .txt file.

How to separate the 2.252016-01-18 from the .txt file into 2 different entries like 2.25 and 2016-01-18 ?

Upvotes: 1

Views: 138

Answers (3)

Brian Rodriguez
Brian Rodriguez

Reputation: 4366

You can build a simple state machine and extract by space delimited strings:

enum Group { DATE_ALONE, COLOR, NUM1, NUM2, NUM3_AND_DATE };

Group state = Group::DATE_ALONE;
std::string str{};
while (logFile >> str) {
    switch (state) {
    case Group::DATE_ALONE:
        auto date = makeDateFromString(str);
        doSomethingWith(date);
        state = Group::COLOR;
        break;
    case Group::COLOR:
        auto color = makeColorFromString(str);
        doSomethingWith(color);
        state = Group::NUM1;
        break;
    // etc...
    case Group::NUM3_AND_DATE:
        auto num = makeNumFromString(str.substr(0, 4));
        doSomethingWith(num);
        auto date = makeDateFromString(str.substr(4));
        doSomethingWith(date);
        state = Group::COLOR; // Skip the `DATE_ALONE` state
        break;
    }
}

Upvotes: 2

procatmer
procatmer

Reputation: 5649

solved. since the value of ratio in the log file are all 3 digit decimal, so i changed the type of ratio to only accept 4 characters (example: 2.13), then i deleted the logFile.ignore(1000, ' '); line. it works and it gives me the result i wanted.

Upvotes: 1

Paul Evans
Paul Evans

Reputation: 27577

Never use !logFile.eof() to test the end of input it doesn't return true at the end of input. Use getline instead, something like:

while ((getline(logFile, l.date, ' ') && (getline(logFile, l.color, ' ')) {
    // ...

Upvotes: 2

Related Questions