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;
}

это мой полный код, а результат - пустая строка.


person shayan    schedule 11.06.2015    source источник


Ответы (2)


Объект fstream имеет позицию в своем выходном файле, и поскольку вы открыли его только для вывода и ввода без каких-либо модификаторов позиции или записи, эта позиция находится в конце файла. Когда вы выводите i в файл, writeFile записывает i в файл, а затем перемещает свою позицию за i, поэтому, когда вы просите его написать больше, вы не перезаписываете i.

Вы можете сбросить позицию до начала файла с помощью вызова writeFile.seekg(0), который помещает эту внутреннюю позицию в позицию 0 в файле (в начале).

Если вам интересно, как управлять потоками, я бы посоветовал взглянуть на cppreference.com и, в частности, документацию по библиотекам ввода и вывода C ++ можно найти здесь.

person jaggedSpire    schedule 11.06.2015

Здесь происходит пара вещей:

  1. Вы не можете открыть файл для чтения, если он не существует, в том числе файл, который вы хотите прочитать и записать. Ни файла, ни открытия.
  2. Как только вам удается открыть файл, поток отслеживает, где он находится в файле. Очевидно, что когда вы читаете или пишете, местоположение перемещается.
  3. There is only one location marker in the stream, so you can read to where you want to write, then write. Unfortunately this means any further reading will pick up after the write. If that's not what you want, get and store the current location (with tellg) before writing, and seek (with seekg) to the stored location after writing.
    1. This has some problems such as what if the block of data you wish to insert is longer or shorter than the block of data you want to overwrite? The simple solution to this problem is read into buffer, edit buffer, write buffer back to file.
  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();

}
person user4581301    schedule 11.06.2015