fstream seekg(),seekp()和write() [英] fstream seekg(), seekp(), and write()

查看:257
本文介绍了fstream seekg(),seekp()和write()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找有关如何 seekg() seekp()您正在写入文件。比如我有一个这样的文件:

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



我想打开该文件,并尝试读取和写入值。

  fstream文件; 
file.open(file.txt,fstream :: in | fstream :: out | fstream :: binary);
file.seekp(0,ios :: end)//寻找到文件末尾
int eofOffset = file.tellp(); //存储文件结束的偏移量,在这种情况下为20

int key = 0;

file.seekg(12,ios :: beg); //将搜索光标从文件开头设置为offset 12
file.read((char *)& key,(int)sizeof(int)); //在接下来的4个字节中读取并分配给键,在这种情况下8
file.seekg(8,ios :: beg); //将搜索光标从文件开头设置为偏移量8
file.read((char *)& key,(int)sizeof(int)); // read in the next 4 bytes and assign it to key,in this case 6

以写入文件的结尾。由于 seekg()函数只移动seek光标,我的 seekp()文件权限?所以:

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

应该使我的文件现在看起来像:

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



现在如果我选择寻找一个偏移量其值作为刚刚插入的值的偏移量。例如,我想让 offset 8 保存 eofOffset = 20 ,因为我们刚刚在那个偏移处插入了12。 >

如果我这样做:

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

是否正确重写我的文件,如下所示:

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

请让我知道如果我使用 seekg() seekp()

解决方案

类模板 std :: basic_filebuf 保存单个文件位置


§27.9.1.1


  1. 类basic_filebuf将输入
    序列和输出序列与

  2. 读取和写入由basic_filebuf类的对象控制的序列的限制与
    读取和写入标准C库FILE时的限制相同。

  3. 特别是:


    • 如果文件未打开,则无法读取输入序列。

    • 如果文件未打开,则无法写入输出序列。

    • 为输入序列和输出序列维持联合文件位置。


是当你使用 std :: basic_fstream 时,它默认使用 std :: basic_filebuf 位置由 seekp() seekg()移动;除非你使用一个单独的变量存储一个位置,这样你可以回到它,你不能跟踪put和获取位置独立。



点2是在 fstream 上的读取和写入之间,必须刷新缓冲区或在从输出更改为输入时查找文件位置,并且必须在结束或在从输入更改为输出时查找文件位置。



有关这些限制的详细信息,请参阅C99标准的第7.19.5.3/7节( fopen 函数)或C11的7.21.5.3/7。


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.

解决方案

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.

这篇关于fstream seekg(),seekp()和write()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆