【问题标题】:C++ std::ofstream - Move the put pointerC++ std::ofstream - 移动放置指针
【发布时间】:2016-02-19 12:50:31
【问题描述】:

我正在将一些数据写入文件。偶尔,我想从内存中写入一个数据块,然后将 put 指针沿 1、2 或 3 个字节移动以保持 4 字节数据边界格式。

我可以创建一个包含零的新数据块并编写它,但这似乎没有必要且笨拙。如何将 put 指针沿 1、2 或 3 个字节移动?

我不知道该怎么做,因为如果我调用seekp(),我肯定会将指针移到当前文件大小之外?而我假设ofstream.write() 正确处理了这个问题?即:它在写入数据时以某种方式调整文件大小?

【问题讨论】:

  • 我很确定除了写点东西之外,不可能有任何其他方式。这就是流类的工作方式。

标签: c++ file ofstream


【解决方案1】:

我假设你正在做类似的事情,除了你想写 4 个字节的数据而不是写两个字节的数据。

#include <fstream>

using namespace std;

struct data
{
    char first;
    char second;
};

int _tmain(int argc, _TCHAR* argv[])
{
    ofstream outFile;
    data data1;
    data data2;

    data1.first = 'a';
    data1.second = 'b';
    data2.first = 'c';
    data2.second = 'd';

    outFile.open("somefile.dat");

    outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
    outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));

    outFile.close();

    return 0;
}

一种选择是简单地将结构设为 4 个字节。这可能有一个缺点,因为它可能会增加内存占用。

使用 seekp 可能不是一个好选择,我试过了,它有点工作,但不是真的。

    outFile.write(reinterpret_cast<char*>(&data1), sizeof(data));
    outFile.seekp(2, ios_base::cur);
    outFile.write(reinterpret_cast<char*>(&data2), sizeof(data));
    outFile.seekp(2, ios_base::cur);

这确实成功地在 data1 但不是 data2 之后添加了填充。将指针移过 just 并不是一个好主意,因为它不会改变文件大小。我尝试在 seekp 之后写入 0 个字节,但这也不起作用。

老实说,我会实现一个辅助函数来提供此功能。这样看起来干净多了。这是一个简单的例子:

#include <fstream>

using namespace std;

struct data
{
    char first;
    char second;
};

void WriteWithPadding(ofstream* outFile, data d, int width);

int _tmain(int argc, _TCHAR* argv[])
{
    ofstream* outFile = new ofstream();
    data data1;
    data data2;

    data1.first = 'a';
    data1.second = 'b';
    data2.first = 'c';
    data2.second = 'd';

    outFile->open("somefile.dat");

    WriteWithPadding(outFile, data1, 4);
    WriteWithPadding(outFile, data1, 4);

    outFile->close();
    delete outFile;

    return 0;
}

void WriteWithPadding(ofstream* outFile, data d, int width)
{
    if (sizeof(d) > width)
        throw;

    width = width - sizeof(d); // width is now amount of padding required
    outFile->write(reinterpret_cast<char*>(&d), sizeof(data));

    // Add Padding
    for (int i = 0; i < width; i++)
    {
        outFile->put(0);
    }
}

【讨论】:

  • 第一篇文章不错!欢迎使用 StackOverflow。
【解决方案2】:

为了迂腐,我假设你已经用ios::binary 打开了你的文件,因为如果你没有打开你的文件,你就会遇到问题。

写入一个文件时,文件的大小仅与您写入文件的字节数一样大。所以如果你把三个字节写入文件,你就会得到一个三个字节的文件。

要保持四字节的分辨率,您必须确保一次写入四个字节——如果您写入一个三字节的对象,请写入一个额外的字节(零?)以使其达到四个字节。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2011-10-27
    • 2020-10-19
    • 2015-04-30
    • 2017-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多