This code is for Hello World output. but it outputs 0x22fed8

I am studying file handling in C ++, but there is a problem here. I am trying to read a file. This code is for Hello World output. but it outputs 0x22fed8.

#include <iostream> #include <fstream> using namespace std; int main() { fstream file; file.open("test.txt",ios::in|ios::out); file << "Hello World"; cout << file; file.close(); return 0; } 

What am I doing wrong?

+14
c ++
Feb 15 '09 at 15:52
source share
4 answers

A simple solution

As others have pointed out, directly printing a file to a stream does not work. To print the contents of a file, you need to open another stream that reads from the file, or reset the read pointer of the stream to the beginning, and then read the entire file again (as others have shown).

C ++ does not do this automatically, but you can do it manually (here, by opening a new thread):

 ifstream ifs("filename"); 

Now writing the contents of the file to another stream is a trivial addition. Instead of writing a file, just write a file buffer:

 cout << ifs.rdbuf() << endl; 

It's all! No loop is required to read the file line by line.

Valid Thread Testing

While we're in the loop course, beware of code that reads files in a loop like this:

 while ( !file.eof() ) 

This code creates an endless loop when there is a read error. This happens in many, many situations. Consider, for example, that a file is deleted while it is being read, or that someone is deleting a USB device containing the file, or that the file is mistakenly formatted. All of these cases would create a cycle of infinity. Never check only eof in a stream.

Fortunately, the solution to this problem is also quite simple. Also, this explains why your source code gave such a weird result. In fact, threads in C ++ have an implicit conversion to type bool . For reasons explained elsewhere (cue: secure bool identification ), it actually converts to void* .

This makes it easy to check if the stream is in an acceptable state, not at the end, and can be read safely. Therefore, we can reformulate the cycle accordingly:

 while (file) â€Ļ 

The above code is based on conversion to void* . Any non- null pointer indicates a valid stream. Now the same thing happens in your code:

 cout << file; 

Since there is no corresponding overload for operator << that takes a stream, C ++ looks for other overloads and finds overload for pointers. Therefore, it implicitly calls something like this:

 cout << static_cast<void*>(file); 

The best decision

I explained the simple, working solution above. However, this solution requires reopening the file and reading it into memory again. This doubles the required work. We can do this better by introducing a new class that acts like a thread and actually sends each output to two threads at the same time. Thus, you can simultaneously write your data both to a file and to a standard stream. No need to re-read the file.

The class itself is pretty simple. The following complete code demonstrates a general principle:

 #include <iostream> #include <fstream> struct sinkpair { sinkpair(std::ostream& a, std::ostream& b) : a(a), b(b) { } // Forward all ouputs to both streams. template <typename T> sinkpair& operator <<(T const& value) { a << value; b << value; return *this; } // Explicit overload needed for manipulators such as `endl`. sinkpair& operator <<(std::ostream& (*manip)(std::ostream&)) { a << manip; b << manip; return *this; } private: std::ostream& a; std::ostream& b; }; int main() { std::ofstream ofs("test.txt"); sinkpair sp(std::cout, ofs); sp << "Hello" << std::endl; } 
+25
Feb 15 '09 at 16:26
source share

EDIT: With tips.

 ifstream fin("file.txt"); if (fin.is_open() == false) { // error } string line; while( getline(fin, line) ) { cout << line; } 
+12
Feb 15 '09 at 16:06
source share

Consider the line

 cout << file; 

The reason the number is displayed is because the file pointer is located deep beneath the fstream hood. By transferring the file to cout, you essentially request cout from fstream. By default, this will be the value of the base file descriptor.

If you want to display the contents of a file, you will need to read it and display it line by line.

 fstream file; file.open("test.txt",ios::in|ios::out); file << "Hello World"; file.seekg (0, ios::beg); while ( !file.eof() ) { string temp; file >> temp; cout << temp << std::eol; } file.close(); 
+7
Feb 15 '09 at 16:00
source share
 #include <iostream> #include <fstream> int main(int, char **) { std::ifstream input("test.txt"); char c; while (input >> c) { std::cout << c; } return 0; } 

Do not include the entire standard namespace. If you want to use the input stream, use ifstream.

You want to display the contents of the file, not the file.

If you want to write to a file, then read it and send it to standard output,

 #include <iostream> #include <fstream> int main(int, char **) { std::fstream file("test.txt",std::ios::in|std::ios::out); file << "Hello" << std::endl; file.seekp(std::ios::beg); char c; while (file >>c) { std::cout << c ; } return 0; } 

Konrad has a better answer, but consider a high-level approach:

 #include <algorithm> #include <iostream> #include <fstream> #include <iterator> int main(int, char **) { std::fstream file("test.txt",std::ios::in|std::ios::out); file << "Hello" << std::endl; file.seekp(std::ios::beg); std::copy( std::istream_iterator<char>(file), std::istream_iterator<char>(), std::ostream_iterator<char>(std::cout) ); return 0; } 
+6
Feb 15 '09 at 16:01
source share



All Articles