LINUX.ORG.RU

Как абстрагиоровать вывод(ввод) в какой-то один объект, не зависимо от того, файл это или же стандартный поток ввода/вывода

 ,


0

2

Странный вопрос, звучит замысловато, но тем не менее, ща попробую объяснить. Вот пускай у меня есть программа, которая должна читать любо файл, либо стандартный ввод, при этом данные в файле имеют точно такой же формат, как и данные, которые я могу вводить стандартным вводом, ну так вот, соотвественно код, который обрабатывает файл/стандартный ввод один и тот же, ну и что дальше, в зависимости от того, указал ли пользователь входной файл или нет, будет производится чтение либо стандартного ввода, либо файла. Ну а т.к. операторы << и >> у классов istream и ifstream, и ostream и ofstream соответственно одинаковы, только объекты разные, а то что стоит с лева от оператора всегда имеет один и тот же формат, (у меня это структура, с перегруженными операторами << и >>), можно как нибудь это обобщить, чтоб код, занимающийся выводом или вводом был один и тот же, а выбор между (стандартным потоком ввода)/(входным файлом) или же (стандартным потоком вывода)/(выходным файлом) производился единажды в начале программы, а дальше просто использовался некий общий объект ввода с оператором >> и некий общий объект вывода с оператором <<? Я наверное описал идею дико не понятно, но тем не менее, если что-то не ясно, переспрашивайте.

Ответ на: комментарий от aol

Ну просто как-то непонятно какой объект использовать, можно ли присваивать объекту istream объект ifstream, ну или например как быть с cout, насколько мне известно его экземпляр может быть только один.

blbulyandavbulyan
() автор топика

Потоки в STL так и задумывались. Вот например.

andalevor ★★★
()
Ответ на: комментарий от aol

Ну и что же я должен прочесть, не подскажите? Просто по запросу «потоки ввода/вывода c++» выдаются довольно таки стандартные примеры либо через стандартный поток ввода/вывода, либо через файл. Но всего вместе нету, как будто кроме этого вообще ничего нет. Короче, дайте пожалуйста ссылку, я же на форум не просто так в конце-то концов пришёл. Я же ведь пришёл за ответом, а ответ «учить матчасть» я его и сам себе могу дать, и какой в этом смысл если я не знаю куда копать-то?

blbulyandavbulyan
() автор топика
Ответ на: комментарий от aol

в воскресенье?

Очнись, приятель! Суббота, мля.

anonymous
()
Ответ на: комментарий от aol

Ты рассчитывал на полезные советы в воскресенье? ))

Сегодня суббота.

blbulyandavbulyan
() автор топика
Последнее исправление: blbulyandavbulyan (всего исправлений: 1)
Ответ на: комментарий от blbulyandavbulyan

либо через стандартный поток ввода/вывода, либо через файл.

В Сишке проще выглядит кстати. Там пофиг стдин, либо файл.

anonymous
()
Ответ на: комментарий от blbulyandavbulyan

Ты должен прочесть про наследование для начала. И вообще какую-нибудь книгу по основам C++. Потом открой документацию на ifstream и посмотри иерархию классов.

rumgot ★★★★★
()

Вот допустим возьму я, и присвою объекту класса ostream экземпляр cout, это же я ведь его скопирую, и в памяти будет лежать уже два таких, ну или присвою я туда объект класса ofstream, как мне потом файл-то закрыть? Ведь у класса ostream нету метода по закрытию файла. И вот чё с этим делать? Ну ладно, поступлю по другому, указателю на объект ostream буду присваивать указатель на cout , а с файлом тогда как быть? Ведь мне же тогда придётся динамически выделить память под объект ofstream и инициализировать его, и как его потом закрыть? Более того, как его потом удалить? Мне же ведь придётся держать его до конца работы моей программы, и дальше я должен буду проверять, был ли открыт файл, как-то преобразовывать указатель на объект ostream в указатель на объект ofstream и высвобождать память, т.е. моя программа опять таки, должна знать что был открыт файл, а я не хочу делать никаких проверок дальше, я хочу получить максимально общий код. Ну и как?

blbulyandavbulyan
() автор топика
Ответ на: комментарий от peregrine

Перегрузки и шаблоны это дело уже пройденное, но я всё равно не понимаю как это применить, вот в моей структурке есть перегруженный оператор ввода/вывода, как в стандартный поток, так и в файл.

blbulyandavbulyan
() автор топика

TL;DR, но думаю, тебе нужно создать наследника от istream/ostream.

Meyer ★★★★★
()
Ответ на: комментарий от blbulyandavbulyan

вот в моей структурке есть перегруженный оператор ввода/вывода, как в стандартный поток, так и в файл.

Зачем там перегрузка, если и файл, и стандартный поток - это наследники ostream?

anonymous
()
Ответ на: комментарий от blbulyandavbulyan

указателю на объект ostream буду присваивать указатель на cout , а с файлом тогда как быть?

Аналогично. Пример:

int doWork(std::ostream &os);

int main(int argc, char *argv[])
{
    if (argc > 1) {
        std::ofstream file(argv[1]);
        if (file) {
            return doWork(file);
        } else {
            return EXIT_FAILURE;
        }
    } else {
        return doWork(std::cout);
    }
}
xaizek ★★★★★
()

А что, справочную информацию люди уже не умеют находить?

seiken ★★★★★
()

Поток ввода-вывода, как и пайпы и тд это всё файловые дескрипторы на уровне ос, что конкретно ты собрался абстрагировать?

anonymous
()
Ответ на: комментарий от blbulyandavbulyan

Да, хоть одну книжку всё же стоит почитать. Тогда был бы известно, что стандартный поток не получится скопировать. А после главы про наследование и примеры из stl всё само собой встанет на места

andalevor ★★★
()
Ответ на: комментарий от anonymous

Сам освободится при завершении

Естественно. Но не всегда всё так просто. Лучше иметь другую привычку.

anonymous
()

Заводишь логику ввода/вывода на std::istream/std::ostream, не понимаю, в чём проблема

XMs ★★★★★
()

ostream istream же.

invy ★★★★★
()
Ответ на: комментарий от anonymous

Лучше иметь привычку думать

Ну-ну. Думать одно, а делать другое. Логично. :)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.