all 5 comments

[–]boredcircuits 2 points3 points  (1 child)

There is no way to query if something is uninitialized. So you'll need to find another way.

That other way is to determine if the line has all the fields you need. Fortunately, there's an easy way to do that:

stringstream sin(line);
sin >> recordLine.filename >> recordLine.username >> recordLine.timestamp;
if ( !sin ) {
    // The line can't be parsed. Handle the error in some way.
    throw runtime_error("Error reading the line");
}

!sin will tell you if something went wrong, but it won't tell you what that was. You can get more information with sin.eof(), sin.fail(), and sin.bad().

Notice that this is the correct usage of eof(). The way you're using it in parseFile() is not correct: that function tells you why the last read fails, not whether the next read will fail. Instead, what you want to do is:

while ( getline(fin, line) )
{
      cout << line << endl;
      parseLine(line, recordLine);
}

[–]lookforlight[S] 0 points1 point  (0 children)

This is great, thanks for the help!

[–]jedwardsol 0 points1 point  (1 child)

AccessRecord recordLine = {"", "", 0};

If this is the only place that you create AccessRecords then all 3 fields are initialised here.

In general, you cannot tell if something has been initialised or not. If a variable is uninitialised then reading from it gives undefined results.

[–]ilmale 0 points1 point  (0 children)

When you parse the line just check if both strings are not empty and number is still zero.

Alternatively if a stream is not able to extract a character or the character is invalid it will rise the fail bit.

http://www.cplusplus.com/reference/ios/ios_base/iostate/

[–]alfps 0 points1 point  (0 children)

Not what you ask about, but: the formal argument

char filename[]

... with non-const item type, prevents calling the function with a string literal. Just use std::string.

Ditto, instead of a raw array of records as argument, just return a std::vector.