473,386 Members | 1,668 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,386 software developers and data experts.

Redirect COUT to file

Hi.

I have problems when I try to redirect everything that is sent to cout
to a file.
I have one piece of code that works and one that does not work.
The only difference is which headers I use.
What the code does:
* First writes "This is sent to prompt" to prompt.
* Then writes "This is sent to file" to file (test.txt).
* Then writes "This is also sent to prompt" to prompt.

Code that works:
##########################################
#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
streambuf* sbuf = cout.rdbuf();
cout.rdbuf(file.rdbuf());
cout << "This is sent to file" << endl;
cout.rdbuf(sbuf);
cout << "This is also sent to prompt" << endl;
return 0;
}
##########################################
Code that DOES NOT work:
##########################################
#include <iostream.h>
#include <fstream.h>

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
streambuf* sbuf = cout.rdbuf();
cout.rdbuf(file.rdbuf()); //ERROR C2660: function does not take 1
parameters
cout << "This is sent to file" << endl;
cout.rdbuf(sbuf); //ERROR C2660: function does not take 1 parameters
cout << "This is also sent to prompt" << endl;
return 0;
}
##########################################

As you can see the only lines that differs are the first 3 lines in
each file.

The error I get is:
andracout.cpp
andracout.cpp(10) : error C2660: 'rdbuf' : function does not take 1
parameters
andracout.cpp(12) : error C2660: 'rdbuf' : function does not take 1
parameters
I compile with:
cl.exe /GX /TP andracout.cpp

cl.exe = Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
12.00.8168 for 80x86
/GX[-] = enable C++ EH (same as /EHsc)
/TP = compile all files as .cpp
Can someone please tell me how to make my code work also with the old
headers.

Now you might ask why I don't just stick with the code that works.

Short explanation why it must work with the old headers:
I can't use the new headers (<iostream> and <fstream>).
I must use the old headers (<iostream.h> and <fstream.h>).

Longer explanation:
The reason why I can't use the new headers (which works in my example)
is that I use a program (ADS from Agilent) that generates all
C++-code. I only give a piece of code to ADS and it will include the
code in some function in a large and complex .cc-file which it will
then compile by automatic, and I can't change the headers it uses.
My problem would be solved if someone could tell me how I can switch
this line in my code:
cout.rdbuf(sbuf);

....to some other piece of code that does the same thing but that does
not use "streambuf* ios::rdbuf ( streambuf* sb );", since it seems
that it is not defined in the .h-files.
I would be very thankful for any information that can help me solve my
problem.

Also, while I have been looking for a solution to my problem I came
across this piece of text that was found in the "basic_ios.h"-file
under my Cygwin-directory. I don't know if this is relevant for me,
but I strongly sense that it is related to my problem:

From "C:\cygwin\usr\include\c++\3.3.1\bits\basic_ios.h" :
#########################################
/**
* @brief Accessing the underlying buffer.
* @return The current stream buffer.
*
* This does not change the state of the stream.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf() const
{ return _M_streambuf; }

/**
* @brief Changing the underlying buffer.
* @param sb The new stream buffer.
* @return The previous stream buffer.
*
* Associates a new buffer with the current stream, and clears
the
* error state.
*
* Due to historical accidents which the LWG refuses to
correct, the
* I/O library suffers from a design error: this function is
hidden
* in derived classes by overrides of the zero-argument @c
rdbuf(),
* which is non-virtual for hysterical raisins. As a result,
you
* must use explicit qualifications to access this function via
any
* derived class.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
#########################################
Can anyone see why I get the error I get and how I can avoid it and
still be using the ".h-headers".
Best Regards
/Omid
Jul 22 '05 #1
6 21027
On 20 Jul 2004 07:26:10 -0700, n_********@hotmail.com (Omid) wrote:
Hi.

I have problems when I try to redirect everything that is sent to cout
to a file.
I have one piece of code that works and one that does not work.
The only difference is which headers I use.
Code that DOES NOT work:
##########################################
#include <iostream.h>
#include <fstream.h>
My compiler (VC 7.1) doesn't have this header at all, so just so you
know, any fix is only temporary; if you upgrade, you're doomed. Fewer
and fewer compilers support any kind of legacy IOstreams...
int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
streambuf* sbuf = cout.rdbuf();
cout.rdbuf(file.rdbuf()); //ERROR C2660: function does not take 1
parameters
cout << "This is sent to file" << endl;
cout.rdbuf(sbuf); //ERROR C2660: function does not take 1 parameters
cout << "This is also sent to prompt" << endl;
return 0;
}
##########################################

cl.exe = Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
12.00.8168 for 80x86
What version is that in English? VC 6?
Can someone please tell me how to make my code work also with the old
headers.
Which old headers? The old headers are non-standard, and differ in
meaning depending upon the exact compiler you are using. I'll assume
you are using Microsoft's old headers.

In that case, you can't write code that works both for the old and new
headers, but here is some code that I suspect will work with the old
headers. Some old iostreams libraries had a class ostream_with_assign,
and if yours is one of them, this is what you need (untested since I
don't have any compilers that are old enough to compile it):

#include <iostream.h>
#include <fstream.h>

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
ostream_with_assign oldcout = cout;
cout = file;
cout << "This is sent to file" << endl;
cout = oldcout;
cout << "This is also sent to prompt" << endl;
return 0;
}
Now you might ask why I don't just stick with the code that works.

Short explanation why it must work with the old headers:
I can't use the new headers (<iostream> and <fstream>).
I must use the old headers (<iostream.h> and <fstream.h>).

Longer explanation:
The reason why I can't use the new headers (which works in my example)
is that I use a program (ADS from Agilent) that generates all
C++-code. I only give a piece of code to ADS and it will include the
code in some function in a large and complex .cc-file which it will
then compile by automatic, and I can't change the headers it uses.
You should get them to fix it, since their code no longer works with
recent compilers.
Also, while I have been looking for a solution to my problem I came
across this piece of text that was found in the "basic_ios.h"-file
under my Cygwin-directory. I don't know if this is relevant for me,
but I strongly sense that it is related to my problem:

From "C:\cygwin\usr\include\c++\3.3.1\bits\basic_ios.h" :
#########################################
/**
* @brief Accessing the underlying buffer.
* @return The current stream buffer.
*
* This does not change the state of the stream.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf() const
{ return _M_streambuf; }

/**
* @brief Changing the underlying buffer.
* @param sb The new stream buffer.
* @return The previous stream buffer.
*
* Associates a new buffer with the current stream, and clears
the
* error state.
*
* Due to historical accidents which the LWG refuses to
correct, the
* I/O library suffers from a design error: this function is
hidden
* in derived classes by overrides of the zero-argument @c
rdbuf(),
* which is non-virtual for hysterical raisins. As a result,
you
* must use explicit qualifications to access this function via
any
* derived class.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
#########################################


I don't think that is relevant to your problem, but I may be wrong.
The above only applies to standard ostreams, and is the reason that:

std::ofstream ofs("Foo.txt");
ofs.rdbuf(std::cout.rdbuf());
doesn't work - you need:
std::ofstream ofs("Foo.txt");
ofs.std::ostream::rdbuf(std::cout.rdbuf());
or similar.

Tom
Jul 22 '05 #2
On 20 Jul 2004 07:26:10 -0700 in comp.lang.c++, n_********@hotmail.com
(Omid) wrote,
Code that DOES NOT work:
##########################################
#include <iostream.h>
#include <fstream.h>


That covers it.
Use of <iostream.h> will lead to code that does not work.

Jul 22 '05 #3
On 20 Jul 2004 07:26:10 -0700, n_********@hotmail.com (Omid) wrote:
Hi. [snip]
Code that works:
##########################################
#include <iostream>
#include <fstream>
using namespace std;
[snip]

Code that DOES NOT work:
##########################################
#include <iostream.h>
#include <fstream.h>


[snip]

It might be far too simple to work, but if you created a file called
iostream.h containing two lines:

- iostream.h ---------------
#include <iostream>
using namespace std;
----------------------------

it might just solve the problem. Keep a backup copy of the old
iostream.h file and put the two liner in the same directory. You
might also need to put a copy of iostream there as well.

Do the same for fstream.h

Might be worth a try.

rossum

--

The ultimate truth is that there is no Ultimate Truth
Jul 22 '05 #4
tom_usenet <to********@hotmail.com> wrote in message news:<6e********************************@4ax.com>. ..
On 20 Jul 2004 07:26:10 -0700, n_********@hotmail.com (Omid) wrote:

cl.exe = Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
12.00.8168 for 80x86


What version is that in English? VC 6?


Yes, that's correct. It's VC 6.0.
I should have mentioned that.

Can someone please tell me how to make my code work also with the old
headers.


Which old headers? The old headers are non-standard, and differ in
meaning depending upon the exact compiler you are using. I'll assume
you are using Microsoft's old headers.

In that case, you can't write code that works both for the old and new
headers, but here is some code that I suspect will work with the old
headers. Some old iostreams libraries had a class ostream_with_assign,
and if yours is one of them, this is what you need (untested since I
don't have any compilers that are old enough to compile it):

#include <iostream.h>
#include <fstream.h>

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
ostream_with_assign oldcout = cout;
cout = file;
cout << "This is sent to file" << endl;
cout = oldcout;
cout << "This is also sent to prompt" << endl;
return 0;
}


Thanks a lot for your help. This was what I was looking for!
However, your "ostream_with_assign" should be changed to
"ostream_withassign", otherwise it's all correct and I'm able to
compile and link this file. So far everything is fine, but when I
execute the exe-file the program crashes and I get this error message:

The instruction at "0x00340905" referenced memory at "0x006811e8". The
memory could not be "written".
(The error is shown in the "standard Windows error window" with an ok
and cancel box.)

The program output:s "This is sent to prompt" and the test.txt is
created with the content "This is sent to file".
But the last message "This is also sent to prompt" isn't sent to
STDOUT.

Does anyone have any idea why this happens?
The compilation and linking is successful,
but during the execution I get this error.
I have also tried several modification of the code above.
One of them that is shown below can successfully be executed with
VC++,
but when I tried to compile exactly the same program with Cygwin g++,
it does not compile.
I'm only using standard headers now.
Why is it possible that it works with VC but not with G++?
Code:

//WORKS FINE WITH CL.EXE (VC++ 6.0)
//BUT NOT WITH CYGWIN G++
//################################
#include <iostream>
#include <fstream>

using namespace std;

class ostream_withassign : public ostream {
public:
ostream_withassign() : ostream((streambuf*)0) {}
~ostream_withassign() {}

ostream_withassign& operator=(ostream& __s) {
ios::init(__s.rdbuf());
return *this;
}
ostream_withassign& operator=(streambuf* __s) {
ios::init(__s);
return *this;
}
};

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
ostream_withassign oldcout; //Split into 2 lines
oldcout= cout; //Split into 2 lines
cout = file;
cout << "This is sent to file" << endl;
cout = oldcout;
cout << "This is also sent to prompt" << endl;
return 0;
}
//################################
Note that I now use the standard header files (without .h).

Error using Cygwin g++ (3.3.1):
################
$ g++ mycout.cpp
/usr/include/c++/3.3.1/bits/ios_base.h: In member function `
std::basic_ios<char, std::char_traits<char> >& std::basic_ios<char,
std::char_traits<char> >::operator=(const std::basic_ios<char,
std::char_traits<char> >&)':
/usr/include/c++/3.3.1/bits/ios_base.h:671: error: `std::ios_base&
std::ios_base::operator=(const std::ios_base&)' is private
mycout.cpp:73: error: within this context
################

For a while I asked myself, is it possible that the problem
that the first program didn't work is in the .h-header files?
First I thought that made sense, but then I tried to compile
this program (using headers without ".h").
//WORKS WITH CYGWIN G++
//BUT NOT WITH CL.EXE (VC++) (compiles, but error when executed)
//################################
#include <iostream>
#include <sstream>
using namespace std;

int main ()
{

int val;
string mystr;
stringstream ss (stringstream::in | stringstream::out);

ss << "120 42 377 6 5 2000";
cout.rdbuf(ss.rdbuf());

for (int n=0; n<6; n++)
{
ss >> val;
cerr << val*2 << '\n';
}

cerr << "Hello World! " << '\n';

return 0;
}
//################################

This compiles and links without problem, and when executed all output
is sent to STDERR (also the last "Hello World" is outputted), but then
the program crashes with this error message:
The instruction at "0x00402f7f" referenced memory at "0x0000000sd".
The memory could not be "read".

The program does work fine Cygwin g++ (3.3.1)! But not with VC 6.0.
(compiled with "g++ test.cpp" and "cl /GX /TP test.cpp" (also compiled
with the entire development VC GUI, but with the same result)).

So now I don't know, is there a problem with my C++-code, or can my VC
be corrupt? Or is there some other explanation?

Once again, thanks to all of you helping me out with this!
Any help, ideas, clues or information is very much appreciated.

/Omid
Jul 22 '05 #5
On 21 Jul 2004 11:32:22 -0700, mi**********@hotmail.com (Omid Rouhani)
wrote:
Thanks a lot for your help. This was what I was looking for!
However, your "ostream_with_assign" should be changed to
"ostream_withassign", otherwise it's all correct and I'm able to
compile and link this file. So far everything is fine, but when I
execute the exe-file the program crashes and I get this error message:

The instruction at "0x00340905" referenced memory at "0x006811e8". The
memory could not be "written".
(The error is shown in the "standard Windows error window" with an ok
and cancel box.)
Hmm, Microsoft still maintain documentation for this:
http://msdn.microsoft.com/library/de...withassign.asp

It seems ostream_withassign doesn't have a correctly defined copy
constructor! So I think you need:

#include <iostream.h>
#include <fstream.h>

int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
ostream_with_assign oldcout;
oldcout = cout;
cout = file;
cout << "This is sent to file" << endl;
cout = oldcout;
cout << "This is also sent to prompt" << endl;
return 0;
}
The program output:s "This is sent to prompt" and the test.txt is
created with the content "This is sent to file".
But the last message "This is also sent to prompt" isn't sent to
STDOUT.

Does anyone have any idea why this happens?
The compilation and linking is successful,
but during the execution I get this error.
I think it's because the copy constructor doesn't do what I thought it
did, so you have to use default construction then assignment.
I have also tried several modification of the code above.
One of them that is shown below can successfully be executed with
VC++,
but when I tried to compile exactly the same program with Cygwin g++,
it does not compile.
I'm only using standard headers now.
Why is it possible that it works with VC but not with G++?
I think it might just be a fluke that it works with VC - the
assignment operator for ostream doesn't do anything useful, and what
you did was undefined behaviour that happened not to crash.
Code:

//WORKS FINE WITH CL.EXE (VC++ 6.0)
//BUT NOT WITH CYGWIN G++ int main ()
{
cout << "This is sent to prompt" << endl;
ofstream file;
file.open ("test.txt");
ostream_withassign oldcout; //Split into 2 lines
oldcout= cout; //Split into 2 lines
Ahh, that's the same change I made above.
cout = file;
That there is the problematic line - cout doesn't have an assignment
operator. The code shouldn't compile at all, but there is a bug in
MSVC6's library that means it does.
cout << "This is sent to file" << endl;
cout = oldcout;
cout << "This is also sent to prompt" << endl;
return 0;
}
//################################
Note that I now use the standard header files (without .h).

Error using Cygwin g++ (3.3.1):
################
$ g++ mycout.cpp
/usr/include/c++/3.3.1/bits/ios_base.h: In member function `
std::basic_ios<char, std::char_traits<char> >& std::basic_ios<char,
std::char_traits<char> >::operator=(const std::basic_ios<char,
std::char_traits<char> >&)':
/usr/include/c++/3.3.1/bits/ios_base.h:671: error: `std::ios_base&
std::ios_base::operator=(const std::ios_base&)' is private
mycout.cpp:73: error: within this context
That error is exactly correct - ios_base::operator= is private, and
therefore the code shouldn't compile. In MSVC6 it wasn't made private,
which is why it compiles successfully there.
//WORKS WITH CYGWIN G++
//BUT NOT WITH CL.EXE (VC++) (compiles, but error when executed)
//################################
#include <iostream>
#include <sstream>
using namespace std;

int main ()
{

int val;
string mystr;
stringstream ss (stringstream::in | stringstream::out);

ss << "120 42 377 6 5 2000";
cout.rdbuf(ss.rdbuf());

for (int n=0; n<6; n++)
{
ss >> val;
cerr << val*2 << '\n';
}

cerr << "Hello World! " << '\n';
Ahh, you're not resetting cout here, so it ends up containing a
dangling pointer to what was ss.rdbuf(). It then probably accesses
that during program shutdown, hence the error you mention below.
Once again, thanks to all of you helping me out with this!
Any help, ideas, clues or information is very much appreciated.


Someone else had the suggestion of forcing ADS to use the new headers
by usurping <iostream.h> with your own version that just includes
<iostream> and puts relevant names into namespace std.

Tom
Jul 22 '05 #6
tom_usenet <to********@hotmail.com> wrote in message news:<da********************************@4ax.com>. ..
On 21 Jul 2004 11:32:22 -0700, minskrappost a_t hotmail.com (Omid Rouhani)
wrote:
Someone else had the suggestion of forcing ADS to use the new headers
by usurping <iostream.h> with your own version that just includes
<iostream> and puts relevant names into namespace std.

Tom


Yes, actually I tried to just replace the .h-files with my own header
files (that included <iostream> and used namespaces). However, it
didn't work since there were stuff in ADS that dependent on that the
old headers should be used and I got tons of errors.

However, I have solved my problems now.
My solution was to create a DLL-file with MinGW(.org) and call
functions in it from ADS.
That is, in my ADS code I just made a call for my own function that
was located in my DLL. Since I use MinGW to create my DLL I can use
any code I want (including using <iostream> and redirecing cout) in my
DLL.
The ADS still compiles using only the .h-files.

Hence, my problem is solved. I can now redirect cout anyway I want in
the DLL-file since it uses the <iostream>-header. No cout-redirection
is made in the code given to ADS.

Once again thanks to all of you taking time helping me out.

/Omid
Jul 22 '05 #7

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

Similar topics

1
by: Damo | last post by:
Could someone please help me. I am a newbie at PHP. I downloaded formail.php Version 5.0 from Jacks scripts( http://www.dtheatre.com/scripts/ )and changed the required areas to my email address and...
3
by: Sean Berry | last post by:
Hi there. I am relativly new to Python CGI and need a question answered. I have made custom 404 error pages and have them in various web directories. I have not been able to figure out a way...
6
by: Tim Stokes | last post by:
Hi all, I want to do a similar action to response.redirect ("file.htm"). But the file.htm contains some sensitive data. I have placed file.htm in a folder in the InetPub...
5
by: Steve Lutz | last post by:
Hello, I have a page that creates a class, and then on certain conditions, redirects user to another page. The class has a Class_Terminate() function that saves itself to a database. The class...
2
by: Jason | last post by:
Hello, I have a class, transCore, that does certain work, and by default, prints its progress to the stand output. Later, I will to write a GUI class that encapsulate the transCore class. I...
3
by: Max | last post by:
Yea this is probably a n00b question, but I haven't programmed C++ in at least 2 years and have never programmed for unix, sorry :) Anyway, I have a project in which a program is required to read...
2
by: Hai Ly Hoang [MT00KSTN] | last post by:
I have a C++ console program which has a lot of output (no input) like this: cout << "Strings here". Now i want to turn this application to windows application (with gui) and I want to bring the...
5
by: Peteroid | last post by:
I'm doing a managed C++ application. Is there a way to re-direct 'cout' to output destinations other than the 'black console' that comes up? Specifically, re-direction to a text file? Thanks in...
2
by: pompom | last post by:
hello all! i have to make a project for school , making a newsserver and a client. the thing is, i send messages between them to let the user know if everything is running ok. just some simple...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.