Why I can not get the same string after using `seekg`?

64 Views Asked by At

I am tring to use seekg to move the pos and then read a line from the .txt. However, I can not get the same string(a completed line) after using seekp, though the pos is same.

The compiler is MinGW 11.2.0 64-bit on x86 windows 11

Here is the test.txt

2   33.10   30.10   29.90   33.00   33.20   33.00   32.90   33.10   40.20   40.20   40.00   39.90   40.30   37.20   40.30   36.70
4   33.00   30.10   29.90   33.00   33.10   32.90   32.90   33.00   40.30   40.20   40.00   40.00   40.30   37.30   40.20   36.70
6   33.00   30.10   29.90   33.00   33.10   33.00   32.90   33.00   40.20   40.30   40.10   40.00   40.20   37.20   40.10   36.90

Here is my code.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(){
string file_path = "./test.txt";
string s;
// don't use seekg
fstream f(file_path);
    getline(f, s);
    int p = f.tellg();
    cout << "the cur pos is:" << p << endl;
    getline(f, s);
    cout << s << endl;
    getline(f, s);
    cout << s << endl;
    f.close();

// use seekg
    fstream t(file_path);
    t.seekg(p, ios::beg);
    p = t.tellg();
    cout << "the cur pos is:" << p << endl;
    getline(t, s);
    cout << s << endl;
}

And the output

the cur pos is:139
2   33.10   30.10   29.90   33.00   33.20   33.00   32.90   33.10   40.20   40.20   40.00   39.90   40.30   37.20   40.30   36.70
4   33.00   30.10   29.90   33.00   33.10   32.90   32.90   33.00   40.30   40.20   40.00   40.00   40.30   37.30   40.20   36.70
the cur pos is:139
2.90    33.10   40.20   40.20   40.00   39.90   40.30   37.20   40.30   36.70

For supplement, here is the string s in memory.

2\t33.10\t30.10\t29.90\t33.00\t33.20\t33.00\t32.90\t33.10\t40.20\t40.20\t40.00\t39.90\t40.30\t37.20\t40.30\t36.70

4\t33.00\t30.10\t29.90\t33.00\t33.10\t32.90\t32.90\t33.00\t40.30\t40.20\t40.00\t40.00\t40.30\t37.30\t40.20\t36.70

2.90\t33.10\t40.20\t40.20\t40.00\t39.90\t40.30\t37.20\t40.30\t36.70

I don't know if it's the problem that there are \ts in the string.

So how can I solve this problem and get a completed line using seekg? It would be appreciated if someone can give me a hand.

1

There are 1 best solutions below

2
Malloc On

Remember to specify the open mode, e.g. ios::binary.

I think I have found the problem. When I open the file, I should specific the mode, e.g., ios::binary. Without that specification, the offset which tellg() returns may be not accurate under some conditions.

So I change

fstream f(file_path);

to

fstream f(file_path, ios::in | ios::binary);

And the value of tellg() gets smaller, which works for me.