powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / из istream в ostream
21 сообщений из 21, страница 1 из 1
из istream в ostream
    #38295346
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток.

Существует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных? Поясню на примере:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
void fconc(const string& f1, const string& f2, const string& rf)
// Объединить содержимое файлов f1 и f2, сохранив результат в файл rf.
{
	ofstream of(rf);	
	if(!of) error("Can't open file ", rf);
	int x;	
	{
		ifstream if1(f1);
		if(!if1) error("Can't open file ", f1);	
		while(if1 >> x) of << x << ' ';
		if(!if1.eof()) error("Reading error ", f1);
	} // здесь поток if1 уничтожается, дозаписывая в файл то, что осталось в буфере	
	ifstream if2(f2);
	if(!if2) error("Can't open file ", f2);
	while(if2 >> x) of << x << ' ';
	if(!if2.eof()) error("Reading error ", f2);
	if(!of) error("Writing error ", rf);
}


В приведённом выше коде я использовал переменную x, считывая значение сначала в неё, а потом читая из неё. Можно ли это промежуточное "колено" как-то исключить, написав код более компактно?

Спасибо.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295357
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumМожно ли это промежуточное "колено" как-то исключить, написав код более
компактно?
Почему бы не так:
Код: sql
1.
of <<if1 <<if2;


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
из istream в ostream
    #38295363
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovПочему бы не так:
Код: sql
1.
of <<if1 <<if2;


И что это означает? И что, если поток if1 достигнет конца раньше, чем if2?

Попробовал ваше предложение в двух вариантах.

1. В этом случае приложение зависает:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
void fconc(const string& f1, const string& f2, const string& rf)
// Объединить содержимое файлов f1 и f2, сохранив результат в файл rf.
{
	ofstream of(rf);	
	if(!of) error("Can't open file ", rf);		
	ifstream if1(f1);
	if(!if1) error("Can't open file ", f1);
	ifstream if2(f2);
	if(!if2) error("Can't open file ", f2);		
	while(of << if1 << if2);
	if(!if1.eof()) error("Reading error ", f1);
	if(!if2.eof()) error("Reading error ", f2);
	if(!of) error("Writing error ", rf);
}



2. Во втором варианте получаю неверный результат в файла, а так же сообщение об ошибке (ошибка чтения файла data1.txt):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
void fconc(const string& f1, const string& f2, const string& rf)
// Объединить содержимое файлов f1 и f2, сохранив результат в файл rf.
{
	ofstream of(rf);	
	if(!of) error("Can't open file ", rf);		
	ifstream if1(f1);
	if(!if1) error("Can't open file ", f1);
	ifstream if2(f2);
	if(!if2) error("Can't open file ", f2);		
	of << if1 << if2;
	if(!if1.eof()) error("Reading error ", f1);
	if(!if2.eof()) error("Reading error ", f2);
	if(!of) error("Writing error ", rf);
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38295366
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пробовал и третий вариант, приводящий так же к зависанию приложения:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
void fconc(const string& f1, const string& f2, const string& rf)
// Объединить содержимое файлов f1 и f2, сохранив результат в файл rf.
{
	ofstream of(rf);	
	if(!of) error("Can't open file ", rf);		
	ifstream if1(f1);
	if(!if1) error("Can't open file ", f1);
	ifstream if2(f2);
	if(!if2) error("Can't open file ", f2);		
	while(if1) of << if1;
	while(if2) of << if2;
	if(!if1.eof()) error("Reading error ", f1);
	if(!if2.eof()) error("Reading error ", f2);
	if(!of) error("Writing error ", rf);
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38295378
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй заменить ifstream на filebuf. Для него есть перегруженный <<.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
из istream в ostream
    #38295537
Фотография Новый Год
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a это точно нужно?

обычно это делают так
cat file1 file2 file3 > Outputfile

если нужно программно -- посмотрите исходники cat
...
Рейтинг: 0 / 0
из istream в ostream
    #38295611
Фотография v6y
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут не совсем понятно что в итоге хочет получить автор топика. То ли скопировать содержимое файлов f1 и f2 в файл rf, то ли получить из этих файлов текстовые представления целых чисел с дальнейшей их записью в файл rf.

В общем случае

cat f1 f2 > rf

и

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
void fconc(const string& f1, const string& f2, const string& rf)
// Объединить содержимое файлов f1 и f2, сохранив результат в файл rf.
{
	ofstream of(rf);	
	if(!of) error("Can't open file ", rf);
	int x;	
	{
		ifstream if1(f1);
		if(!if1) error("Can't open file ", f1);	
		while(if1 >> x) of << x << ' ';
		if(!if1.eof()) error("Reading error ", f1);
	} // здесь поток if1 уничтожается, дозаписывая в файл то, что осталось в буфере	
	ifstream if2(f2);
	if(!if2) error("Can't open file ", f2);
	while(if2 >> x) of << x << ' ';
	if(!if2.eof()) error("Reading error ", f2);
	if(!of) error("Writing error ", rf);
}



выдадут разные результаты.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295629
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новый Годa это точно нужно?

обычно это делают так
cat file1 file2 file3 > Outputfile

если нужно программно -- посмотрите исходники catЯ не спрашивал о том, как перенаправлять потоки средствами командных оболочек.
v6yТут не совсем понятно что в итоге хочет получить автор топика. То ли скопировать содержимое файлов f1 и f2 в файл rf, то ли получить из этих файлов текстовые представления целых чисел с дальнейшей их записью в файл rf.Вы оба невнимательно читали мой вопрос.

Автор топика чётко обозначил вопрос, показав его суть на простом примере, который присутствует лишь для наглядности оного.
Сам вопрос достаточно чёток и ясен:
автор топикаСуществует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных?
Поскольку это форум по программированию на C++, то очевидно, что вопрос задан в контексте использования этого языка.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295641
Фотография v6y
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumАвтор топика чётко обозначил вопрос, показав его суть на простом примере, который присутствует лишь для наглядности оного.
Сам вопрос достаточно чёток и ясен:
автор топикаСуществует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных?

Конкретно ваш пример есть не перенаправление содержимого istream в ostream, а именно форматированое чтение из одного потока и форматированная запись в другой. Это не совсем одно и тоже и поэтому позволяет неоднозначное интерпретирование того, что в конечном итоге нужно получить.

автор топикаСуществует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных?
Насколько я знаю, нет.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295741
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CompositumСуществует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
#include <algorithm>
#include <iostream>
#include <cstdarg>
#include <fstream>
using namespace std;

void fconc(const char *rf, ...) {
	va_list vargs;
	va_start(vargs, rf);
	ofstream fout(rf);
	while (char *name = va_arg(vargs, char*)) {
		ifstream fin(name);
		copy(
			istreambuf_iterator<char>(fin),
			istreambuf_iterator<char>(),
			ostreambuf_iterator<char>(fout)
		);
		fin.close();
	}
	fout.close();
	va_end(vargs);
}

int main() {
	fconc("C:\\1.txt", "C:\\boot.ini", "C:\\Windows\\system.ini", "C:\\Windows\\win.ini");
	return 0;
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38295785
Фотография v6y
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanCompositumСуществует ли более компактный способ перенаправления содержимого istream в ostream, минуя использование дополнительных переменных?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
#include <algorithm>
#include <iostream>
#include <cstdarg>
#include <fstream>
using namespace std;

void fconc(const char *rf, ...) {
	va_list vargs;
	va_start(vargs, rf);
	ofstream fout(rf);
	while (char *name = va_arg(vargs, char*)) {
		ifstream fin(name);
		copy(
			istreambuf_iterator<char>(fin),
			istreambuf_iterator<char>(),
			ostreambuf_iterator<char>(fout)
		);
		fin.close();
	}
	fout.close();
	va_end(vargs);
}

int main() {
	fconc("C:\\1.txt", "C:\\boot.ini", "C:\\Windows\\system.ini", "C:\\Windows\\win.ini");
	return 0;
}



Я хотел предложить похожий вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
ostream & sconc(const istream & is, ostream &os) {
 if (!is) throw string("Error");
 copy(
   istreambuf_iterator<char>(is.rdbuf()),
   istreambuf_iterator<char>(),
   ostreambuf_iterator<char>(os)
 );

 return os;
}

void fconc(const string& f1, const string& f2, const string& rf)  {
 ofstream of(rf);
 sconc(ifstream(f2), sconc(ifstream(f1),of));
 of.close();
}



Но меня смутило
авторминуя использование дополнительных переменных
...
Рейтинг: 0 / 0
из istream в ostream
    #38295788
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman,

Благодарю, интересный код. Я внёс в него небольшие косметические изменения и запустил, но получил сообщение: Can't open input file .
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
/*
test.cpp
http://www.sql.ru/forum/1028906/iz-istream-v-ostream#14426593
Перенаправление нескольких потоков ввода в поток вывода, без использования промежуточных 
переменных.
*/
#include <algorithm>
#include <iostream>
#include <cstdarg>
#include <fstream>
using namespace std;
void fconc(const char *rf, ...)
// Объединение содержимого файлов в один, имя которого указано в rf.
{
	va_list vargs;
	va_start(vargs, rf);
	ofstream fout(rf);
	if(!fout) throw runtime_error("Can't open output file."); // обязательно проверяем состояние
	while (char *name = va_arg(vargs, char*)) {
		ifstream fin(name);
		if(!fin) throw runtime_error("Can't open input file."); // обязательно проверяем состояние
		copy(
			istreambuf_iterator<char>(fin),
			istreambuf_iterator<char>(),
			ostreambuf_iterator<char>(fout)
		);
		// fin.close(); // в этом нет необходимости
	}
	// fout.close();  // в этом нет необходимости
	va_end(vargs);
}
//==================================================================================================
int main()
try{
	fconc("C:\\bs\\1.txt", "C:\\boot.ini", "C:\\Windows\\system.ini", "C:\\Windows\\win.ini");	
}
catch(exception& e){
	cerr << e.what() << endl;
	return 1;
}
catch(...){
	cerr << "Unknown exception." << endl;
	return 2;
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38295822
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Нужно проверить пути:

- C:\boot.ini
- C:\Windows\system.ini
- C:\Windows\win.ini

В Windows XP/2003 это стандартные системные файлы (должно работать).
В Seven - возможно уже по-другому.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295831
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
v6y,

Спасибо, попробовал и ваш код, немного подкорректировав его:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
/*
test.cpp
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1028906&msg=14425267
Перенаправление нескольких потоков ввода в поток вывода, без использования промежуточных 
переменных.
*/
//--------------------------------------------------------------------------------------------------
#include <algorithm>
#include <iostream>
#include <cstdarg>
#include <fstream>
using namespace std;
//--------------------------------------------------------------------------------------------------
ostream& sconc(const istream& is, ostream& os) {
 if(!is) throw runtime_error("Can't open input file."); // обязательно проверяем состояние
 copy(
   istreambuf_iterator<char>(is.rdbuf()),
   istreambuf_iterator<char>(),
   ostreambuf_iterator<char>(os)
 );
 return os;
}
//--------------------------------------------------------------------------------------------------
void fconc(const string& f1, const string& f2, const string& rf)  {
 ofstream of(rf.c_str());
 if(!of) throw runtime_error("Can't open output file."); // обязательно проверяем состояние
 ifstream if2(f2.c_str());
 if(!if2) throw runtime_error("Can't open input file."); // обязательно проверяем состояние
 ifstream if1(f1.c_str());
 if(!if1) throw runtime_error("Can't open input file."); // обязательно проверяем состояние
 sconc(if2, sconc(if1,of));
 // of.close(); // в этом нет необходимости
}
//==================================================================================================
int main()
try{
	fconc("C:\\boot.ini", "C:\\Windows\\system.ini", "C:\\bs\\1.txt");	
}
catch(exception& e){
	cerr << e.what() << endl;
	return 1;
}
catch(...){
	cerr << "Unknown exception." << endl;
	return 2;
}


К сожалению, в результате получаю так же Can't open input file .
...
Рейтинг: 0 / 0
из istream в ostream
    #38295839
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UsmanCompositum,

Нужно проверить пути:

- C:\boot.ini
- C:\Windows\system.ini
- C:\Windows\win.ini

В Windows XP/2003 это стандартные системные файлы (должно работать).
В Seven - возможно уже по-другому.
опа... я проверил второй и третий, упустив проверку первого. :) Да, похоже, что в Windows 7 x64 отсутствует файл C:\boot.ini. Убрал его, и оба варианта кода (ваш и код v6y ) сразу заработал, спасибо!

А используя операторы "<<" и ">>", выполняя посимвольное перенаправление, можно написать более компактный вариант, чем указал я (даже если отбросить добавляемые мною символы пробелов)?

Спасибо.
...
Рейтинг: 0 / 0
из istream в ostream
    #38295893
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Без функции copy , но с буферизацией (считывает весь файл в строку):
Код: plaintext
1.
fout << string(istreambuf_iterator<char>(fin), istreambuf_iterator<char>()).c_str();
...
Рейтинг: 0 / 0
из istream в ostream
    #38296068
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Compositum,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
ofstream& operator<<(ofstream& fout, ifstream& fin)
{
	copy(
		istreambuf_iterator<char>(fin),
		istreambuf_iterator<char>(),
		ostreambuf_iterator<char>(fout)
	);
	return fout;
}

void fconc(const char *rf, ...) {
	va_list vargs;
	va_start(vargs, rf);
	ofstream fout(rf);
	while (char *name = va_arg(vargs, char*)) {
		ifstream fin(name);
		fout << fin;
	}
	va_end(vargs);
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38296230
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так что не подходит?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
template <typename Ostream, typename Istream>
void copy_stream(Ostream& os, Istream& is)
{
    os << is.rdbuf();
}

int main()
{
    ifstream is("/etc/hosts");
    copy_stream(cout, is);
    return 0;
}
...
Рейтинг: 0 / 0
из istream в ostream
    #38296248
итераторы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
может, использовать std::copy, std::ostream_iterator и std::istream_operator (детали по памяти не вспомню, но по идее должно делаться в 1 строчку)?
...
Рейтинг: 0 / 0
из istream в ostream
    #38296295
Фотография v6y
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА так что не подходит?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
template <typename Ostream, typename Istream>
void copy_stream(Ostream& os, Istream& is)
{
    os << is.rdbuf();
}

int main()
{
    ifstream is("/etc/hosts");
    copy_stream(cout, is);
    return 0;
}



Тьфу блин, я чего то просмотрел что у ostream есть
Код: plaintext
1.
ostream& operator<< (streambuf* sb )



Вот и нагородил огород :)
...
Рейтинг: 0 / 0
из istream в ostream
    #38296419
Фотография Compositum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Благодарю всех за ответы. Как освобожусь - буду изучать предложенные варианты.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / из istream в ostream
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]