This seems to be a bug...
I tried putting in debug statements.
Your code works if you have a newline character at the end of the last line.
strangely,
if you don't have a newline at the end, the in.readAll() call returns
"line number 6"

if you do, it returns
"number 6"

In both the cases the pos value remains the same.
So as a possible work around you should probably append a new line at the end of file.

Another strange observation. I did some experiment,
I took the file without the last line containing a newline at the end and did a in.readAll().size(). It returned me 163 which is correct.
Then I added a new line at the end of the last line and did the same thing. It returned me 159 which is very strange, whereas it should have returned me 165. Therefore it clearly is a bug. You should log one.

Running this on a Windows machine by any chance? Your logic allows for the length of each unmatched line plus one byte. On Windows the end-of-line marker is two bytes. So, for each unmatched line you read your pos value is incremented by one byte less than it should be. When you slurp pos bytes at the end you are slurping fewer bytes that you should be.

I'd use a different approach that is not fussed by line endings. If the files are typically small then something like:
@
const QString lookingFor("blah");
QFile file("h:/test.txt");
if (file.open(QFile::ReadOnly)) { // line ending conversion not wanted
QByteArray data = s.readAll();
const int pos = data.indexOf(lookingFor.toUtf8());
// must allow for encoding differences ^^^^^^^^
if (pos >= 0)
data.truncate(pos);
}
QString result = QString::fromUtf8(data);
@
I assume the file is UTF8 encoded, you might need to adjust.

If EOL is two bytes, then why I get the expected result for all lines except for the last? I should be losing one character for every line but that is not the case. Compensating with two bytes for each line doesn't produce the expected behavior either.

Yes, we all agree the solution is not ideal, but the thread is not about a better solution but about the strange behavior this one produces.

What puzzles me is why the inconsistency. If the problem is in the EOL character being 2 bytes, then I should be losing a character for each line. But no characters are lost save for the last line. That's what I am failing to understand why and would like to know.

I cannot reproduce any issue with the first solution: whether the code is run on Windows, Linux, with either line ending, with or without a trailing EOL marker on the last line. I don't see prady_80's "bug" or your inconsistent behaviour.