Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fstream seekg(), seekp(), and write()

Tags:

I'm looking for some clarification on how seekg() and seekp() works with respect to when you are writing to a file. Say for instance I had a file like so:

offset 0: 2 offset 4: 4 offset 8: 6 offset 12: 8 offset 16: 10 

Now I want to open the file and do some seeks to read and write values.

fstream file; file.open("file.txt", fstream::in |fstream::out | fstream::binary); file.seekp(0, ios::end) // seek to the end of the file int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20  int key = 0;  file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8 file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6 

Now I want to write to the end of the file. Since the seekg() function only moves the seek cursor, my seekp() cursor should still be at the end of the file right? So:

int newKey = 12; file.write((char *) &newKey, sizeof(int)); 

should make my file now look like:

offset 0: 2 offset 4: 4 offset 8: 6 offset 12: 8 offset 16: 10 offset 20: 12 

Now what happens to my file if I choose to seek to an offset and write its value as the offset to the value that was just inserted. For example, I want offset 8 to hold eofOffset = 20 since we just inserted 12 at that offset.

If I do:

file.seekp(8, ios::beg); file.write((char *) &eofOffset, sizeof(int)); 

does it correctly rewrite my file to look like this:

offset 0: 2 offset 4: 4 offset 8: 20 offset 12: 8 offset 16: 10 offset 20: 12 

Please let me know if I am making any errors using the seekg() and seekp() functions.

like image 308
raphnguyen Avatar asked Mar 27 '13 22:03

raphnguyen


People also ask

What is the use of seekg () and Seekp () functions?

seekg() and seekp() both are functions of File Handling in C++ and they are very important and useful feature of File Handling in C++. In File Handling of C++, we have two pointers one is get pointer and second is put pointer.

What is the difference between seekg and Seekp?

Use seekp() to position the file position before writing. Use seekg() to position the file position before reading. If you use one, don't for get to use the other.

What are the differences between the two classes file and fstream?

fstream is a better encapsulation and has higher level concepts. fstream is exception safe. fstream is also a stream and can be treated generically as a stream.


1 Answers

The class template std::basic_filebuf holds a single file position

§ 27.9.1.1

  1. The class basic_filebuf associates both the input sequence and the output sequence with a file.
  2. The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf are the same as for reading and writing with the Standard C library FILEs.
  3. In particular:
    • If the file is not open for reading the input sequence cannot be read.
    • If the file is not open for writing the output sequence cannot be written.
    • A joint file position is maintained for both the input sequence and the output sequence.

What this means is that when you use a std::basic_fstream, which by default uses a std::basic_filebuf, the single file position is moved by both seekp() and seekg(); unless you use a separate variable to store one of the positions so you can then seek back to it, you cannot keep track of put and get positions independently.

The implications of point 2 are that between reads and writes on an fstream you must either flush the buffer or seek the file position when changing from output to input, and you must either be at the end of the file or seek the file position when changing from input to output.

For detail on these restrictions, see section 7.19.5.3/7 of the C99 standard ("The fopen function"), or 7.21.5.3/7 of C11.

like image 138
user657267 Avatar answered Sep 28 '22 09:09

user657267