473,397 Members | 2,028 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Redirection of Streams

I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?

Mar 21 '06 #1
14 2299

Gaijinco wrote:
I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?


You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;

Mar 22 '06 #2
JH Trauntvein wrote:
Gaijinco wrote:
I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?


You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;


Or, preferably, references to streams.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 22 '06 #3
Ben Pope wrote:
JH Trauntvein wrote:
Gaijinco wrote:
I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?


You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;


Or, preferably, references to streams.


How would you go about this particular problem using references instead of
pointers. The whole point of using a pointer to a stream rather than a
stream was to be able to make it point to a different stream depending on
the outcome of some test. With a reference, that won't fly: you cannot
reseat a reference.
Best

Kai-Uwe Bux
Mar 22 '06 #4
Kai-Uwe Bux wrote:
Ben Pope wrote:

JH Trauntvein wrote:
Gaijinco wrote:

I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?

You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;


Or, preferably, references to streams.

How would you go about this particular problem using references instead of
pointers. The whole point of using a pointer to a stream rather than a
stream was to be able to make it point to a different stream depending on
the outcome of some test. With a reference, that won't fly: you cannot
reseat a reference.
Best

Kai-Uwe Bux


std::istream& is = std::cin;
std::ifstream ifs ("data.in");
if (ifs) is = ifs;
// use is after this.
Mar 22 '06 #5
Kai-Uwe Bux wrote:
Ben Pope wrote:
JH Trauntvein wrote:
Gaijinco wrote:
I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:

FILE *id=fopen("data.in","r");

if(!id)
id=stdin;

I have read about streams but I haven't found how to do it, I suppose
it must look like:
fstream id("data.in",ios::in)

if(!id)
// what must be written here so id stream is "connected" to cin?
You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;

Or, preferably, references to streams.


How would you go about this particular problem using references instead of
pointers. The whole point of using a pointer to a stream rather than a
stream was to be able to make it point to a different stream depending on
the outcome of some test. With a reference, that won't fly: you cannot
reseat a reference.

#include <iostream>
#include <fstream>

void doSomethingToOStream(std::ostream& os) {
os << "something";
}

int main() {
/* VC8 says the following needs a copy constructor,
* I'm not sure if that's correct; I've found a bug in
* VC8 that unnecessarily requires a copy constructor.
* I'm not sure if it applies here.
*
bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;
*/

// A solution is:
std::ofstream ofs("test");
if (ofs) {
doSomethingToOStream(ofs);
} else {
doSomethingToOStream(std::cout);
}
}

I don't think it's particularly outrageous to create a function that
operates on an istream to solve the problem though.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 22 '06 #6
Milan Cvetkovic wrote:
Kai-Uwe Bux wrote:

you cannot reseat a reference.


std::istream& is = std::cin;
std::ifstream ifs ("data.in");
if (ifs) is = ifs;
// use is after this.


You didn't compile that, did you?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 22 '06 #7
> > std::istream& is = std::cin;
std::ifstream ifs ("data.in");
if (ifs) is = ifs;
// use is after this.


Fixing this post:
std::ifstream ifs ("data.in");
if (ifs) ifs = std::cin;
// use ifs after this.

Mar 22 '06 #8
Ben Pope wrote:
Kai-Uwe Bux wrote:
Ben Pope wrote:
JH Trauntvein wrote:
Gaijinco wrote:
> I used C for a long time where I could open a file for input but if
> the file didn't existed, then I redirected the input to the standard
> input, something like:
>
> FILE *id=fopen("data.in","r");
>
> if(!id)
> id=stdin;
>
> I have read about streams but I haven't found how to do it, I suppose
> it must look like:
>
>
> fstream id("data.in",ios::in)
>
> if(!id)
> // what must be written here so id stream is "connected" to cin?
You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in))
in = &std::cin;
Or, preferably, references to streams.
How would you go about this particular problem using references instead
of pointers. The whole point of using a pointer to a stream rather than a
stream was to be able to make it point to a different stream depending on
the outcome of some test. With a reference, that won't fly: you cannot
reseat a reference.

#include <iostream>
#include <fstream>

void doSomethingToOStream(std::ostream& os) {
os << "something";
}

int main() {
/* VC8 says the following needs a copy constructor,
* I'm not sure if that's correct; I've found a bug in
* VC8 that unnecessarily requires a copy constructor.
* I'm not sure if it applies here.
*
bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;
*/

// A solution is:
std::ofstream ofs("test");
if (ofs) {
doSomethingToOStream(ofs);
} else {
doSomethingToOStream(std::cout);
}


I would call that a work around :-)
}

I don't think it's particularly outrageous to create a function that
operates on an istream to solve the problem though.


I tried

bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;

and it works. I also think, it is required to work. However, this only works
once. Using a pointer, you can redirect the stream multiple times.

Maybe, one should have a little wrapper class around a stream pointer. That
way, one could have stream objects that support assignment. (I am thinking
of something like a reference count based pointer and the last guy closes
the stream).
Best

Kai-Uwe Bux
Mar 23 '06 #9
he***************@gmail.com wrote:
> std::istream& is = std::cin;
> std::ifstream ifs ("data.in");
> if (ifs) is = ifs;
> // use is after this.


Fixing this post:
std::ifstream ifs ("data.in");
if (ifs) ifs = std::cin;
// use ifs after this.


And exactly how would that be a fix? You might get:

no match for 'operator=' in 'ifs = std::cin'
Best

Kai-Uwe Bux
Mar 23 '06 #10
Kai-Uwe Bux wrote:
Ben Pope wrote:
// A solution is:
std::ofstream ofs("test");
if (ofs) {
doSomethingToOStream(ofs);
} else {
doSomethingToOStream(std::cout);
}
I would call that a work around :-)


Fair enough :-)
}

I don't think it's particularly outrageous to create a function that
operates on an istream to solve the problem though.


I tried

bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;

and it works. I also think, it is required to work.


Yeah, this looks a lot like a bug I found in VC8. I had code that had
(publicly) inherited from a stringstream, but provided a proper copy
constructor that initialised the stringstream base in the initialiser
list. Throwing this object gave me the same error: cannot access
private member in compiler generated function (copy constructor of
stringstream).

I've informed MS.
However, this only works
once. Using a pointer, you can redirect the stream multiple times.
Understood. That's why the function call is just neater all round.
Maybe, one should have a little wrapper class around a stream pointer. That
way, one could have stream objects that support assignment. (I am thinking
of something like a reference count based pointer and the last guy closes
the stream).


Sounds neat as well, thanks for your insight.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 23 '06 #11
Ben Pope wrote:
Kai-Uwe Bux wrote:
I tried

bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;

and it works. I also think, it is required to work.


Yeah, this looks a lot like a bug I found in VC8. I had code that had
(publicly) inherited from a stringstream, but provided a proper copy
constructor that initialised the stringstream base in the initialiser
list. Throwing this object gave me the same error: cannot access
private member in compiler generated function (copy constructor of
stringstream).


Hm, that is a little different. I think

std:ostream& os = validFile ? ofs : std::cout;

is required to work because it does *not* invoke any copy constructors. This
line is just initializing a reference from an lvalue [5.16/4] -- I am
assuking here that ofs and std::cout have the same type.

However, something like

std::stringstream i_str = some_cond ? str_stream_1 : str_stream_2;

is an entirely different matter (note the absence of &). In this case, a
copy constructor is invoked which for streams, I think, is required to
fail.
Best

Kai-Uwe Bux
Mar 23 '06 #12
Kai-Uwe Bux wrote:
Ben Pope wrote:
Kai-Uwe Bux wrote:
I tried

bool validFile = ofs;
std::ostream& os = validFile ? ofs : std::cout;

and it works. I also think, it is required to work.


Yeah, this looks a lot like a bug I found in VC8. I had code that had
(publicly) inherited from a stringstream, but provided a proper copy
constructor that initialised the stringstream base in the initialiser
list. Throwing this object gave me the same error: cannot access
private member in compiler generated function (copy constructor of
stringstream).


Hm, that is a little different. I think

std:ostream& os = validFile ? ofs : std::cout;

is required to work because it does *not* invoke any copy constructors. This
line is just initializing a reference from an lvalue [5.16/4] -- I am
assuking here that ofs and std::cout have the same type.

However, something like

std::stringstream i_str = some_cond ? str_stream_1 : str_stream_2;

is an entirely different matter (note the absence of &). In this case, a
copy constructor is invoked which for streams, I think, is required to
fail.


I understand that. Consider:

#include <sstream>
#include <iostream>

class fail : public std::stringstream {
public:
fail() : std::stringstream() {}
fail(const fail& rhs) : std::stringstream(std::ios::in |
std::ios::out) {}
};

int main() {
try {
throw fail();
} catch(fail& e) {
}
}

I have provided a perfectly acceptable, although, admittedly not great,
copy constructor, yet VC8 fails compilation with the following error:

C:\Program Files\Microsoft Visual Studio 8\VC\include\sstream(513) :
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access
private member declared in class 'std::basic_ios<_Elem,_Traits>'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\ios(151)
: see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
This diagnostic occurred in the compiler generated function
'std::basic_stringstream<_Elem,_Traits,_Alloc>::ba sic_stringstream(const
std::basic_stringstream<_Elem,_Traits,_Alloc> &)'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>
]

<snip similar errors cascaded into istream and ostream>

It has attempted to create a copy constructor for the stringstream base,
even though one is not required (I have provided a copy constructor for
fail, that does not require a copy constructor for the base).

This is the reason why I believe the previous compilation of:

std:ostream& os = validFile ? ofs : std::cout;

Also fails; for some reason it requires (and attempts to create) a copy
constructor of the stringstream, even though one is technically not
required.

Comeau online compiles it, and I'm pretty sure VC7.1 and GCC 4.x compile it.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Mar 23 '06 #13
Ben Pope wrote:
Kai-Uwe Bux wrote:
[snip]
However, something like

std::stringstream i_str = some_cond ? str_stream_1 : str_stream_2;

is an entirely different matter (note the absence of &). In this case, a
copy constructor is invoked which for streams, I think, is required to
fail.
I understand that. Consider:

#include <sstream>
#include <iostream>

class fail : public std::stringstream {
public:
fail() : std::stringstream() {}
fail(const fail& rhs) : std::stringstream(std::ios::in |
std::ios::out) {}
};

int main() {
try {
throw fail();
} catch(fail& e) {
}
}

I have provided a perfectly acceptable, although, admittedly not great,
copy constructor, yet VC8 fails compilation with the following error:

C:\Program Files\Microsoft Visual Studio 8\VC\include\sstream(513) :
error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access
private member declared in class 'std::basic_ios<_Elem,_Traits>'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
C:\Program Files\Microsoft Visual Studio 8\VC\include\ios(151)
: see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
This diagnostic occurred in the compiler generated function
'std::basic_stringstream<_Elem,_Traits,_Alloc>::ba sic_stringstream(const
std::basic_stringstream<_Elem,_Traits,_Alloc> &)'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>
]

<snip similar errors cascaded into istream and ostream>

It has attempted to create a copy constructor for the stringstream base,
even though one is not required (I have provided a copy constructor for
fail, that does not require a copy constructor for the base).


I see. You are right, that looks like a bug.

This is the reason why I believe the previous compilation of:

std:ostream& os = validFile ? ofs : std::cout;

Also fails; for some reason it requires (and attempts to create) a copy
constructor of the stringstream, even though one is technically not
required.

Comeau online compiles it, and I'm pretty sure VC7.1 and GCC 4.x compile
it.


I checked: g++-4.1.0 compiles it.
Best

Kai-Uwe Bux
Mar 24 '06 #14

JH Trauntvein wrote:
Gaijinco wrote:
I used C for a long time where I could open a file for input but if the
file didn't existed, then I redirected the input to the standard input,
something like:
.... You could actually do this by using pointers to stream objects as in
the following:

std::istream *in = new std::ifstream("data.in");
if(!(*in)) {
delete in; // Garbage collection is usually not enabled. in = &std::cin;

}

HTH,
Michiel Salters

Mar 24 '06 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Ronald Legere | last post by:
The new itertools stuff is pretty cool. One thing that bothers me though is that there seems to be no way to copy an iterator. How does one work around this? Is there a trick that I am missing? ...
52
by: Gerard M Foley | last post by:
Can one write a webpage which is not displayed but which simply redirects the user to another page without any action by the user? Sorry if this is simple, but I am sometimes simple myself. ...
4
by: Edwin G. Castro | last post by:
I want to start a process from a C# application. I also want to redirect standard error to standard output so that I can read output from both streams just like I could from a command line. In...
1
by: Chris | last post by:
I'm reading up on streams and I have two articles that seem to conflict with each other. One article describes streams and lists a few of the major ones (FileStream, Memory Stream, Network...
8
by: Luciano A. Ferrer | last post by:
Hi! I was following the http://www.seomoz.org/articles/301-redirects.php article, trying to do that with one of my test sites I added this to the .htaccess file: RewriteEngine On RewriteCond...
13
by: souissipro | last post by:
Hi, I have written a C program that does some of the functionalities mentionned in my previous topic posted some days ago. This shell should: 1- execute input commands from standard input,...
1
by: comp.lang.php | last post by:
require_once("/users/ppowell/web/php_global_vars.php"); if ($_GET) { // INITIALIZE VARS $fileID = @fopen("$userPath/xml/redirect.xml", 'r'); $stuff = @fread($fileID,...
3
by: postindex | last post by:
Can I get whole commandline not only argument list. 1. When I command like this $ a.py filename 2. sys.argv is returns only argument list Is there a way to find out 'redirection'...
13
by: Massimo Fabbri | last post by:
Maybe it's a little OT, but I'll give it try anyway.... I was asked to maintain and further develop an already existing small company's web site. I know the golden rule of "eternal" URIs, but...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.