fstream使用格式化数据

时间:2015-06-11 20:31:45

标签: c++ stream fstream

我是这个网站的新手,这是我的第一个问题! 我对fstream功能有疑问。

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

fstream用于输入和输出,所以当我们像这样使用它时,在输出和输入两者之前有一个new.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;
}

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

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

在这里发生一些事情:

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

    #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();
    
    }