После использования getline, невозможно записать в файл - PullRequest
2 голосов
/ 06 февраля 2011

Я создаю большую библиотеку файлового ввода-вывода и в настоящее время борюсь с совместимостью getline () и записью в файл. Мой вопрос ниже очень похож на этот, но, к сожалению, остается без ответа: C ++ После того, как я использую getline для чтения из файла, я больше не могу писать в текстовый файл

Как только я использую getline (), я больше не могу писать в файл. Запросы на чтение с помощью getline () будут продолжать работать, но запросы на запись не будут выполнены. Однако, если я закомментирую использование getline (), операции записи будут успешными.

Мой код размещен ниже. Я заметил, что сбой бит активируется после первой попытки записи. Однако причина этого возникновения мне неизвестна, так как она не активна, если я удаляю операции getline ().

Мне должно быть ясно - я могу читать из существующего файла (который содержит две строки) отлично. Однако я не могу записать в этот файл, если не удалю операторы getline ().

Любая помощь, как всегда, ценится.

// Includes
#include <fstream>
#include <iostream>
#include <string>

// Namespace
using namespace std;

int main(){
    // filestream object
    fstream workFile("testdoc.txt"); //fstream uses ios::in | ios::out by default
    // note that I have tried including ios::in | ios::out to no avail

    // read from file
    string grabbedLine;
    getline(workFile, grabbedLine);
    cout << "Line #1: " << grabbedLine << endl;

    // write to file
    workFile<< "Here is some output (#1)" << endl;

    // read from file
    getline(workFile, grabbedLine);
    cout << "Line #2: " << grabbedLine << endl;

    // write to file
    workFile<< "Here is some output (#2)" << endl;

    // wait for some input...
    getchar();
}

Current console output (as expected from text file):
Line #1: This is line#1
Line #2: This is line#2

Ответы [ 6 ]

3 голосов
/ 06 февраля 2011

Основываясь на некоторых экспериментах, похоже, что оператор << ожидает, что смещение будет в конце файла.Я не могу объяснить это точно, но похоже, что смещение не там, где оно ожидается после того, как вы позвоните getline().Мне удалось заставить запись в файл работать, добавив строку:

workFile.seekg(ios_base::end);

непосредственно перед записью в файл.Однако это сместит смещение в конец файла и неправильно прочитает вторую строку после.

Я думаю, вы хотите открыть два файловых дескриптора, один из которых вы будете читать, а другой - в:

int main(){
    // filestream object
    fstream workFileRead("testdoc.txt", ios_base::in);
    fstream workFileWrite("testdoc.txt" , ios_base::app | ios_base::out);

    // read from file
    string grabbedLine;
    getline(workFileRead, grabbedLine);
    cout << "Line #1: " << grabbedLine << endl;

    // write to file
    workFileWrite << "Here is some output (#1)" << endl;

    // read from file
    getline(workFileRead, grabbedLine);
    cout << "Line #2: " << grabbedLine << endl;

    // write to file
    workFileWrite<< "Here is some output (#2)" << endl;

    // wait for some input...
    getchar();
}
2 голосов
/ 12 ноября 2012

Я знаю, что это старый пост, но я только столкнулся с той же проблемой и продолжал нажимать на этот пост без ответа в поиске Google. ...

Мне удалось заставить это работать. Как объяснено в связанном посте, чтение в конец файла с помощью getline () устанавливает бит Fail. Это должно быть очищено, и указатель установлен в правильном месте для записи, прежде чем запись будет успешной ... например мой код, чтобы прочитать последнюю строку файла, а затем написать что-то:

fstream myfile;
char line[10];
string myText;

myfile.open("test.txt", ios::in | ios::out);
while ( myfile.getline(line,10) )
{  myText = line; }  //myText is left storing the last line

myfile.clear();
myfile.seekp(0, ios::end);
myfile << "Writing to this file!!!" << endl;
myfile.close();
1 голос
/ 06 февраля 2011

У fstream есть только одна позиция потока, общая для чтения и записи. Таким образом, вы действительно должны искать при переключении между чтением и письмом. Вы можете использовать одну из функций Tell, чтобы сохранить текущую позицию чтения или записи, а затем выполнить поиск, когда хотите продолжить.

Открытие файла дважды для получения двух позиций потока, скорее всего, НЕ является хорошей идеей. Если операционная система вообще позволяет вам делать это, вы, вероятно, перепутаете содержимое файла различными способами.

0 голосов
/ 13 июля 2018

Это решается с помощью функции read() вместо getline().

0 голосов
/ 06 февраля 2011

Файл, скорее всего, не открыт для вывода, поэтому вместо

fstream workFile("testdoc.txt");

используйте следующие

fstream workFile("testdoc.txt", fstream::in | fstream::out);
0 голосов
/ 06 февраля 2011

Подумайте, что << делает с файлом: он записывает в него, и, поскольку вы можете читать из него, мы знаем, что он был открыт для добавления. ) В противном случае файл сначала будет обрезан, и чтение не будет выполнено успешно.) Когда вы записываете данные в файл, смещение файла автоматически находится в конце файла , так что теперь больше ничего нет читать.

Теперь вы можете обойти это, используя lseek (2) или методы, которые его обертывают, например fstream::tellg, но я держу пари, что вы действительно хочет создать временный файл для вывода, записать все в этот файл, а затем переместить временный файл обратно, чтобы заменить исходный.

Обновление

Извините, уже поздно, и я поменял смысл вопроса. Если вообще ничего не происходит, то, скорее всего, у вас нет файла, который можно было бы написать. Вы проверили флаг fail? См. Документы для класса iostream :: fstream , где написано:

Создает объект из потока учебный класс. Это подразумевает инициализацию связанного объекта filebuf и вызов конструктора его базовый класс с объектом filebuf как параметр.

Дополнительно, когда второй версия конструктора используется, Поток связан с физическим подать как будто звонок члену функция открытия с одинаковыми параметрами было сделано.

Если конструктор не успешен при открытии файла объект все еще создан, хотя нет файла связанный с буфером потока и бит бит потока установлен (который может быть проверенным с унаследованным членом сбой).

...