files seekg and seekp always returning the same value

Conserning binary output files:

Shouldn't get and put flags have separate values?

When I output them, they both have the same values independently of me setting seekp(0) and seekg(3) for instance.

So my question is, are they separate values, or it's just one flag with different names?
seekp and seekg return a reference to the stream. You should be using tellp and tellg to output the position of the put and get pointers, respectively.
I couldn't make myself clear, sorry.

I use tellg and tellp to output the position flag.

However they always output the same value.

Imagine the following code:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
      fstream file;
      file.open("some.bin", ios::out | ios::in | ios::binary);

      file.seekp(3);
      file.seekg(300);

      int a=file.tellg;
      int b=file.tellp;
}


In this case a==b, while they should be: a=300 and b=3. Right?

EDIT: Another question, if you're willing to anwser:

How can I tell if a file was created before. Imagine I want to run some statements only the first time I open a file and the program might be run a number of times.
Last edited on
Another problem:

When the file was not created before this statement:

1
2
3
4
5
6
7
8
9
10
11
int Scale::open_file()
{
    database.open("scl_dat.bin", ios::out | ios::in | ios::binary); //FIXME

    if(!database.is_open())
        {
            return 0;
        }

    return 1;
}


Fails to open a new file. However if I remove the ios::in flag it opens it successfully. Can anyone explain me why?


EDIT:

I ended up with this solution to check if my file had been created before, but it just doesn't seem all that pretty, although it works.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int Scale::open_file()
{
    //checking if the file was created before:
    database.open("scl_dat.bin", ios::in | ios::binary);

    if(!database.is_open())
       {
           int a=sizeof(a);
           database.open("scl_dat.bin", ios::out | ios::binary);
           database.write((char*)(&a),a);
           database.close();
           return open_file();
       }

    database.close();
    //End of check.
    database.open("scl_dat.bin", ios::out |ios::in | ios::binary); //FIXME

    if(!database.is_open())
        {
            return 0;
        }

    return 1;
}
Last edited on
when you open a fstream with in | out, VS converts it to a "r+" inside its code. Now r+ will only work if the file already exists. You can do a stepin to see that. So this may be the problem if you are on windows.

so either you give a in or out or if you want to read and write, give a ios::app also.

try it.
I am indeed using Windows.

if a set the flags like this:

fstream file("myfile.bin", ios::out | ios::in | ios::binary | ios::app);

The program runs smoothly as you said it would. Thanks.

That's one problem solved.

What about tellg and tellp returning the same values?

EDIT: This is what I'm asking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    fstream file("myfile2.bin", ios::out | ios::in | ios::binary | ios::app);
    if(!file.is_open())
        {
            cout<<"Cannot open file.\n";
            return -1;
        }

    file.seekp(3);
    file.seekg(2);

    cout<<"p: "<<file.tellp()<<"\n"<<"g: "<<file.tellg()<<"\n";

    return 0;
}


output is:

1
2
p: 2
g: 2
while I believe it should be "p: 3 \n g:2"..
Last edited on
Essentially, a stream only maintains one pointer. Since you're dealing with one file, the put and get pointers will always point to the same location. If you reversed your seeking above, that is, if you did:

1
2
file.seekg(2);
file.seekp(3);

then your program will output 3 for both.

Now, if you were reading from one file and writing to another it would be different. You could seekg in the in-file (and tellg would report that correctly) and you could seekp in the out-file (and tellp would report that correctly). Note that you can't call seekp/tellp on an instance of ifstream and you can't call seekg/tellg on an instance of ofstream. However, you can use both on an instance of fstream.

If you want to be reading and writing to the same file with seeking, you need to maintain your own get and put pointers, and seek to those (and update them as needed).
Last edited on
Understood.

Thanks,

Hugo Ribeira
Topic archived. No new replies allowed.