0
votes

I'm currently working on code for parsing a file with an unknown number of lines. The format is roughly like this:

ShapeId: 1
ShapeType: Line
ShapeDimensions: 20, 90, 100, 20
PenColor: blue
PenWidth: 2
PenStyle: DashDotLine
PenCapStyle: FlatCap
PenJoinStyle: MiterJoin

// and so on and so forth; formats vary slightly depending on the entry

Being a text file, obviously we'll want to check for errors. Currently, I am doing this by throwing an exceptions with (fairly) informative messages.

However, my exception messages cannot be too specific, because many of my functions which help parse the file are too generic to have specific messages. Given the sheer diversity of the lines, it's impractical to have custom-written messages for each kind of line.

As I mentioned in the title, I am using QTextStream. I am using readLine to read the each line, and then doing stuff with that line. I am also using skipWhiteSpace to skip the gaps between the blocks of data.

I was hoping QTextStream would come with this functionality, but it doesn't. The closest thing I could find is pos. This is better than nothing, but it's not nearly as useful as a line number.

I could add an integer counter to count up as I step through each line. However, this is impractical in the context of my program, where I have many helper functions that will read lines. Also, skipWhiteSpace can skip multiple lines, so I couldn't use this if I were manually counting.

Unfortunately, I haven't been able to find a good solution. The closest would be something like this, but that's assuming we're already stepping through the file, one line at a time, within a simple loop. Again, that's too impractical in this situation.

So...I guess my question is: is there an elegant way of checking the line number which a QTextStream is pointing to without relying on any previous code? Am I missing something obvious?

(I would rather avoid using on libraries other than Qt and the basic C++ libraries for this.)

3

3 Answers

1
votes

I think the answer is NO. If you look in QTextStreamPrivate there are no member fields that contain line count. The class itself do not need it.

You can also look at the scan() method, that is used to read lines, for hints.

0
votes

Just an idea: if you can get your current position with QTextStream::pos() function, you can calculate the line number by reading the whole text before that position and count the new line characters in that string. Something like:

qint64 currentPos = stream.pos();
QString str = stream.read(currentPos);
int lineNum = str.count(QRegExp("\\r\\n?|\\n")) + 1;

This may be slow, however you need the line number only for error reporting, so calling it once would be ok.

0
votes

You could wrap the QTextStream in something that counted lines.

class StreamWithLineCount
{
    QTextStream stream;
    int lineCount;
public:
    QString readLine(qint64 maxlen = 0)
    {
        ++lineCount;
        return stream.readLine(maxLen);
    }

    void skipWhitespace()
    {
         qint64 pos = stream.pos(); 
         while (!stream.atEnd() && readLine().simplified().isEmpty()) 
         {
             pos = stream.pos();
         }        
         seek(pos);
    }
}