std :: getline с помощью std :: fstream - PullRequest
1 голос
/ 11 октября 2019

Я использую std::fstream для чтения и записи в один и тот же файл. Я могу видеть, что происходит запись, но не чтение.

После поиска в Интернете я узнал, что не могу одновременно установить режим и приложение. Итак, избавился от этого и сделал очень простым, не передавая никаких аргументов.

Мне очень интересно узнать причину, по которой чтение не происходит.

Кроме того, как люди читают изаписать в тот же файл, используя тот же файл fstream?

Мой код:

#include<iostream>
#include<fstream>

int main() {
  std::fstream* fs = new std::fstream("xx.txt");
  *fs << "Hello" << std::endl;
  (*fs).close(); // ?

  std::string line;
  while(std::getline(*fs, line)) {
    std::cout << line << std::endl;
  }
}

С помощью этого кода я могу xx.txt содержать «Hello» в качестве содержимого, но он не входит внутрьцикл while вообще заявляет, что чтение не удалось.

Как я могу преодолеть это?

Ответы [ 2 ]

1 голос
/ 11 октября 2019

Я попытаюсь объяснить проблему.

Оператор std::fstream* fs = new std::fstream("xx.txt"); откроет файл, если он существует в режиме по умолчанию "in | out". Если файл не существует, то вызов open из конструктора std :: fstream не будет выполнен. И это можно проверить, проверив failbit с помощью функции fail (). Таким образом, вам явно потребуется вызвать open, чтобы использовать объект fstream для ввода данных. Примечание: новый файл не будет создан, пока вы не вызовете 'close'.

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

ИтакВ качестве альтернативы, вы всегда должны вызывать 'open', который будет работать в обоих случаях (если файл существует или нет).

#include<iostream>
#include<fstream>


int main() {
    //std::fstream fs("xx.txt");
    //std::cout << fs.fail() << std::endl; // print if file open failed or passed
    std::fstream fs;  
    fs.open("xx.txt", std::fstream::in | std::fstream::out | std::fstream::app);
    std::cout << fs.fail() << std::endl;
    fs << "Hello" << std::endl;

    if (fs.is_open())
    {   
        std::cout << "Operation successfully performed\n";
        fs.close();
    }
    else
    {   
        std::cout << "Error opening file";
    }

Для чтения содержимого файла вам сначала необходимо закрыть файл. А потом снова откройте и прочитайте. Как я понимаю, когда вы начнете использовать объект fs для вставки, вы не сможете прочитать с него, если вы явно не закроете его и не откроете снова.

    fs.open("xx.txt", std::fstream::in | std::fstream::out);
    std::string line;
    while(std::getline(fs, line)) {
        std::cout << line << std::endl;
    }
    std::cout << "end" << std::endl;
    fs.close();
}
1 голос
/ 11 октября 2019

Вы забыли снова открыть поток. На самом деле вы не можете открыть поток в обоих направлениях (одновременно). Итак, шаги:

  • Открыть поток для записи
  • Запись данных
  • Закрыть поток
  • Открыть поток для чтения
  • Чтение данных
  • Закройте его (необязательно)

Ваш образец может быть переписан как:

#include <fstream>
#include <iostream>

int main()
{
    const std::string file_path("xx.txt");

    std::fstream fs(file_path, std::fstream::app);
    if(fs) // Check if the opening has not failed
    {
        fs << "Hello" << std::endl;
        fs.close();
    }

    fs.open(file_path, std::fstream::in);
    if(fs) // Check if the opening has not failed
    {
        std::string line;
        while(std::getline(fs, line))
        {
            std::cout << line << std::endl;
        }
        fs.close();
    }

    return 0;
}

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

...