使用格式化数据的 fstream

fstream using formatted data

本文关键字:fstream 格式化数据      更新时间:2023-10-16

我是这个网站的新手,这是我的第一个问题!我有一个关于 Fstream 函数的问题。

fstream f("new.dat",ios::out|ios::in);

fStream是同时用于输入和输出的,所以当我们这样使用它时,在它输出和输入之前有一个新的.dat文件。 但奇怪的是,当我这样做时,它会正确输出数据,但无法输入。我发现如果你关闭它,然后重新打开它,它会输入.为什么会这样??

int main()
{
    fstream writeFile("newFile.dat", ios::out|ios::in);
    char i[3];
    char u[3]="HI";
    if (!writeFile)
    {
        cerr << "error" << endl;
    }
    writeFile << u <<endl;
    writeFile >> i;
    cout << i << endl;
}

这是我的完整代码,结果是一个空行。

fstream 对象在其输出文件中有一个位置,并且由于您打开它只是为了输出和输入而没有任何位置或写入修饰符,因此该位置位于文件的末尾。将i输出到文件时,writeFile i写入文件,然后将其位置移动到i之后,因此当您要求它写入更多内容时,不会覆盖i

您可以通过调用 writeFile.seekg(0) 将位置重置为文件的开头,这会将该内部位置放置在文件中的0位置(在开头)。

如果您对流操作感到好奇,我建议您在此处查看 cppreference.com,特别是有关 c++ 输入和输出库的文档。

这里有几件事:

  1. 如果文件不存在,则无法打开文件进行读取,这包括要读取和写入的文件。没有文件,没有打开。
  2. 一旦您设法打开文件,流就会跟踪它在文件中的位置。当您阅读或写作时,位置显然会移动。
  3. 流中只有一个位置标记,因此您可以读取到要写入的位置,然后写入。不幸的是,这意味着任何进一步的阅读将在写入后继续。如果这不是您想要的,请在写入之前获取并存储当前位置(使用 tellg),并在写入后查找(使用 seekg)到存储的位置。
    1. 这有一些问题,例如,如果您要插入的数据块比要覆盖的数据块长或短怎么办?此问题的简单解决方案是读入缓冲区,编辑缓冲区,将缓冲区写回文件。
  4. 当您打开文件并开始写入文件时,会覆盖文件中的任何内容。如果要添加到文件,请使用ios::app打开。这会将流的位置设置为文件的末尾。我不知道有任何类型的插入会在您写入新数据时推动现有数据。

一些简单的文件处理示例代码

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
    fstream f1("filename", ios::out);
    if (f1.is_open())
    {
        if (f1 << "Hi")
        {
            cout << "wrote"<<endl;
        }
        f1.close();
    }
    fstream f2("filename", ios::out|ios::app);
    if (f2.is_open())
    {
        if (f2 << " there!")
        {
            cout << "appended"<<endl;
        }
        f2.close();
    }
    fstream f3("filename", ios::in);
    if (f3.is_open())
    {
        cout << f3.rdbuf()<< endl;
        f3.close();
    }
    fstream f4("filename", ios::in|ios::out);
    if (f4.is_open())
    {
        f4.seekg(3);
        if (f4 << "Fred!")
        {
            cout << "overwrote"<<endl;
        }
        f4.close();
    }
    fstream f5("filename", ios::in);
    if (f5.is_open())
    {
        cout << f5.rdbuf()<< endl;
        f5.close();
    }
// note the extra ! on the end left over from Hi there! I do not know how
// to get rid of this. I have always just done stuff like this to get around it.
    fstream f6("filename", ios::in);
    stringstream s1;
    string token;
    f6 >> token;
    s1 << token << " Tim!";
    f6.close();
    fstream f7("filename", ios::out);
    f7 << s1.rdbuf();
    f7.close();
// and then moved temp over filename.
    fstream f8("filename", ios::in);
    cout << f8.rdbuf()<< endl;
    f8.close();
}